Showing posts with label WPF. Show all posts
Showing posts with label WPF. Show all posts

Friday, April 13, 2012

WPF : Determining if user is running same application instance on a terminal server

Please refer to this article in which I showed how we can determine if user is trying to run same application instance, this approach will work on single user Desktop machine, but it will not work when there are multiple users connecting to a terminal server and are trying to run same application. What happens is if a user start application, and then if some other user tries to start same application then it fails saying that application is already running because it doesn't distinguishes 2 users, so in this article I am going to show how we can change the old logic to consider individual user also.


private void Application_Startup(object sender, StartupEventArgs e)
{        
 string processname = Process.GetCurrentProcess().ProcessName + ".exe";
 string currentuserid = GetLoggedInUserName(); //This function should return Loggedin user name, you can put your logic here.
 totaluserapplicationinstance = 0;
 
 System.Management.ManagementObjectSearcher Processes = new System.Management.ManagementObject Searcher("SELECT * FROM Win32_Process Where Name ='" + processname + "'");
               
 foreach (System.Management.ManagementObject process in Processes.Get())
 {
  string[] OwnerInfo = new string[2];
  process.InvokeMethod("GetOwner", (object[])OwnerInfo);
  if (OwnerInfo[0].Equals(currentuserid))
  {
   totaluserapplicationinstance++;
  }
 }
 
 alreadyloggedin = totaluserapplicationinstance > 1;
 if (alreadyloggedin)
 {
  Messagebox.Show("You are already running an instance of same application");
  App.Current.Shutdown();
  return;
 }
}

Wednesday, March 28, 2012

WPF : Create a Hover over menu and show tab header in 2 lines for Infragistic Tab control

Requirement : In this post I am going to create a hover over menu, which will display a list of actions user can take whenever he moves his mouse over a textblock. I am also going to show how we can break tabheader text into 2 lines to reduce horizontal space taken by tab headers in Infragistic tab header contol.

Here is how application will look

Before user moves over Launch action



After user movers over Launch

Approach: I am going to create a user control which will use a label control ("lblLaunch" in my example) , a popup control which will hold a list of labels to indicates actions.

Here is my code for HoveroverMenu.xaml user control

<UserControl x:Class="CaseTrail.HoveroverMenu"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             Height="Auto" Width="Auto">
 <UserControl.Resources>
  <ControlTemplate x:Key="LabelControlTemplate1" TargetType="{x:Type Label}">
   <Border x:Name="brdName" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
    <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                <Border.Background>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="Black" Offset="1"/>
                        <GradientStop Color="#FFEDE7E7" Offset="0.196"/>
                    </LinearGradientBrush>
                </Border.Background>
            </Border>
   <ControlTemplate.Triggers>
    <Trigger Property="IsEnabled" Value="False">
     <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
    </Trigger>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" TargetName="brdName">
                        <Setter.Value>
                            <SolidColorBrush Color="#FFA7A2A2" />
                        </Setter.Value>
                    </Setter>
                </Trigger>
            </ControlTemplate.Triggers>
  </ControlTemplate>
 </UserControl.Resources>
    <StackPanel>
        <Label Width="100" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" x:Name="lblLaunch"  Grid.Column="1" Mouse.MouseMove="Button_MouseMove">
            <Label.Background>
          <LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
           <GradientStop Color="#FFF3F3F3" Offset="0"/>
           <GradientStop Color="#FFEBEBEB" Offset="0.5"/>
           <GradientStop Color="#FFDDDDDD" Offset="0.5"/>
           <GradientStop Color="#FF45479F" Offset="1"/>
          </LinearGradientBrush>
            </Label.Background>
            
            <Label.Content>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Launch"></TextBlock>
                    <Path Margin="10,4,0,0"  Data="M160,24 L175.5,23.5 167.5,31.5 z" Fill="Blue" HorizontalAlignment="Left" Stretch="Fill" Stroke="Black" VerticalAlignment="Top" />
                </StackPanel>
            </Label.Content>
        </Label>
        
        <Popup Width="100"  x:Name="controls" StaysOpen="False"  >
            <ItemsControl Background="AliceBlue">
                <Label HorizontalContentAlignment="Center" Mouse.MouseDown="Label_MouseDown" VerticalContentAlignment="Center" HorizontalAlignment="Stretch" Content="Client Cases" Template="{DynamicResource LabelControlTemplate1}" />
                <Label HorizontalContentAlignment="Center" Mouse.MouseDown="Label_MouseDown" Template="{DynamicResource LabelControlTemplate1}"  VerticalContentAlignment="Center" HorizontalAlignment="Stretch" Content="Forms &amp; Letters" />
                <Label HorizontalContentAlignment="Center" Mouse.MouseDown="Label_MouseDown" Template="{DynamicResource LabelControlTemplate1}"  VerticalContentAlignment="Center" HorizontalAlignment="Stretch" Content="Search Rep." />
                <Label HorizontalContentAlignment="Center" Mouse.MouseDown="Label_MouseDown" Template="{DynamicResource LabelControlTemplate1}"  VerticalContentAlignment="Center" HorizontalAlignment="Stretch" Content="Log Call" />
            </ItemsControl>
        </Popup>
 
    </StackPanel>
</UserControl> 
 
 
 Here is my code for HoveroverMenu.xaml.cs file
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
 
namespace CaseTrail
{
    /// <summary>
    /// Interaction logic for HoveroverMenu.xaml
    /// </summary>
    public partial class HoveroverMenu : UserControl
    {
        public HoveroverMenu()
        {
            InitializeComponent();
        }
 
        private void Button_MouseMove(object sender, MouseEventArgs e)
        {
            if (!controls.IsOpen)
            controls.IsOpen = true;
        }
 
        private void Label_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Label l = e.Source as Label;
            MessageBox.Show(l.Content.ToString());
        }
    }
} 
 
 
I am going to use my HoveroverMenu control in my view MainWindow.xaml file as shown below
 
<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:igWindows="http://infragistics.com/Windows" xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" x:Class="CaseTrail.MainWindow"
    xmlns:local="clr-namespace:CaseTrail"    
    Title="MainWindow" Height="350" Width="625">
    
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <igWindows:XamTabControl VerticalAlignment="Stretch" Grid.RowSpan="2" Grid.ColumnSpan="2" x:Name="xamTabControl1"  Theme="Office2k7Blue" ShowTabHeaderCloseButton="True" AllowTabClosing="True"   >
            
            <igWindows:TabItemEx  MaxWidth="100"   >
                <igWindows:TabItemEx.Header>
                    <TextBlock MaxWidth="100" Height="35" TextWrapping="Wrap" Text="Case (Opened)"></TextBlock>
                </igWindows:TabItemEx.Header>
                <Grid />
            </igWindows:TabItemEx>
 
            <igWindows:TabItemEx  MaxWidth="100"   >
                <igWindows:TabItemEx.Header>
                    <TextBlock MaxWidth="100" Height="35" TextWrapping="Wrap" Text="Merge"></TextBlock>
                </igWindows:TabItemEx.Header>
                <Grid />
            </igWindows:TabItemEx>
            <igWindows:TabItemEx  MaxWidth="100"   >
                <igWindows:TabItemEx.Header>
                    <TextBlock MaxWidth="100" Height="35" TextWrapping="Wrap" Text="Clone"></TextBlock>
                </igWindows:TabItemEx.Header>
                <Grid />
            </igWindows:TabItemEx>
            <igWindows:TabItemEx MaxWidth="100"   >
                <igWindows:TabItemEx.Header>
                    <TextBlock MaxWidth="100" Height="35" TextWrapping="Wrap" Text="Related"></TextBlock>
                </igWindows:TabItemEx.Header>
                <Grid />
            </igWindows:TabItemEx>
            <igWindows:TabItemEx  MaxWidth="100"   >
                <igWindows:TabItemEx.Header>
                    <TextBlock MaxWidth="100" Height="35" TextWrapping="Wrap" Text="Related Cases"></TextBlock>
                </igWindows:TabItemEx.Header>
                <Grid />
            </igWindows:TabItemEx>
            <igWindows:TabItemEx MaxWidth="100"  >
                <igWindows:TabItemEx.Header>
                    <TextBlock MaxWidth="100" Height="35" TextWrapping="Wrap" Text="Client View"></TextBlock>
                </igWindows:TabItemEx.Header>
                <Grid />
            </igWindows:TabItemEx>
        </igWindows:XamTabControl>
        
        <local:HoveroverMenu Grid.Column="1" Margin="0,5,5,0" />
           
    </Grid>
</Window> 
 
 
 
 

Thursday, March 22, 2012

WPF (C#) : Make sure only one instance of your application is running

In this article I am going to show how to figure out if your application is already running and you don't want to start a new instance of application.
I am going to write this method in Application_Startup event in WPF, but this logic can be used in Winforms also.

In Your Application_Startup , Check if there is already a process running which has same name like your process and if yes then that means application is already running and exit.

Here is sample App.xaml.cs file


public partial class App : Application
    {
        #region Variables
        bool alreadyloggedin = false;
        #endregion
 
        #region Events
 
 
        private void Application_Startup(object sender, StartupEventArgs e)
        {
 
            Process[] processlist = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName);
            alreadyloggedin = processlist.Length > 1;
 
          
 
            if (alreadyloggedin)
            {
                MessageBox.Show("Application is already running");
                App.Current.Shutdown();
                return;
            }
 
            
        }
 
       
 
        #endregion
    }

Tuesday, March 13, 2012

WPF : Implement IsolatedStorageSettings in WPF

In this post I am going to implement IsolatedStorageSettings in WPF. 
Lets start with a brief introduction to IsolatedStorageSettings, Its a storage which is used for storing application configurations and it uses IsolatedStore to store those setting. Its a builtin feature in Silverlight but not available in WPF. In WPF we have ApplcationSettings , but it uses App.config to store application settings.


Why do we need IsolatedStorageSetting in WPF ?
We had a requirement where user should be able to store application setting but user will not have access to read/write any file including App.config file so we needed to be able to read write these settings at a path where users will always have access irrespective of their security settings.


Lets look at code below
1) I am going to create a new class CustomIsolatedStorageSettings which will be derived from IDictionary<string,Object>. we are deriving it from IDictionary because we want it to be like a dictionary object where we should be able to store object against their keys.


2) I am going to have use Singleton design patter to expose this class, that's why i have made private constructor and used a static constructor which initializes Instance property and also custom appDictionary object which is used to store all keys and objects.


3) I have a ReadData method which is called in static constructor , it reads file from IsolatedStorage and sets key values in appDictionary. It reads file CustomIsolatedStorage.bin which is stored in binary format and deserializes into appDictionary.



4) I have a Save method which is called whenever any key is updated. It formats appDictionary in a binary stream and saves that stream using IsolatedStorageStream in CustomIsolatedStorage.bin file.



/// <summary>
    /// This class is implemented to store user settings in an Isolated storage file.
    /// </summary>
    public class CustomIsolatedStorageSettings : IDictionary<string,Object>
    {
        #region Constants/Variables
        static Dictionary<stringobject> appDictionary = new Dictionary<stringobject>();
        static CustomIsolatedStorageSettings CustomIsolatedStorageSettings = new CustomIsolatedStorageSettings();
        const string filename = "CustomIsolatedStorage.bin";
        #endregion
 
        #region Singleton Implementation
 
        /// <summary>
        /// Its a private constructor.
        /// </summary>
        private CustomIsolatedStorageSettings()
        {
            
        }
 
        /// <summary>
        /// Its a static singleton instance.
        /// </summary>
        public static CustomIsolatedStorageSettings Instance
        {
            get
            {
                return CustomIsolatedStorageSettings;
            }
        }
 
        /// <summary>
        /// Its static constructor.
        /// </summary>
        static CustomIsolatedStorageSettings()
        {
            LoadData();
        }
 
        private static void LoadData()
        {
            IsolatedStorageFile isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, nullnull);
 
            if ( isoStore.GetFileNames(filename).Length == 0 )    
            {        
                // File not exists. Let us NOT try to DeSerialize it.        
                return;    
            }        
            
            // Read the stream from Isolated Storage.    
            Stream stream = new IsolatedStorageFileStream( filename,FileMode.OpenOrCreate, isoStore );    
            if ( stream != null )    
            {        
                try        
                {            
                    // DeSerialize the Dictionary from stream.            
                    IFormatter formatter = new BinaryFormatter();            
                    Dictionary<string,Object> appData = ( Dictionary<string,Object>) formatter.Deserialize(stream);                        
                    
                    // Enumerate through the collection and load our Dictionary.            
                    IDictionaryEnumerator enumerator = appData.GetEnumerator();            
                    while ( enumerator.MoveNext() )            
                    {
                        appDictionary[enumerator.Key.ToString()] = enumerator.Value;            
                    }        
                }        
                finally        
                {            
                    stream.Close();        
                }
    
            }
        }
 
        #endregion
 
        #region Methods
        /// <summary>
        /// It serializes dictionary in binary format and stores it in a binary file.
        /// </summary>
        public void Save()
        {
            IsolatedStorageFile isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, nullnull);
 
            Stream stream = new IsolatedStorageFileStream(filename,FileMode.Create, isoStore );
            if ( stream != null )    
            {        
                try        
                {            
                    // Serialize dictionary into the IsolatedStorage.            
                    IFormatter formatter = new BinaryFormatter();            
                    formatter.Serialize( stream, appDictionary );        
                }        
                finally        
                {            
                    stream.Close();        
                }    
            }
        }
 
        /// <summary>
        /// It Checks if Dictionary object has item corresponding to passed key,
        /// if True then it returns that object else it returns default value.
        /// </summary>
        /// <param name="key"></param>
        /// <param name="defaultvalue"></param>
        /// <returns></returns>
        public object this[string key, Object defaultvalue]
        {
            get
            {
                if (appDictionary.ContainsKey(key))
                {
                    return appDictionary[key];
                }
                else
                {
                    return defaultvalue;
                }
            }
            set
            {
                appDictionary[key] = value;
                Save();
            }
        }
 
        #endregion
 
        #region IDictionary<string, object> Members
 
        public void Add(string key, object value)
        {
            appDictionary.Add(key, value);
            Save();
        }
 
        public bool ContainsKey(string key)
        {
            return appDictionary.ContainsKey(key);
        }
 
        public ICollection<string> Keys
        {
            get { return appDictionary.Keys; }
        }
 
        public bool Remove(string key)
        {
            try
            {
                Save();
                appDictionary.Remove(key);
                return true;
            }
            catch
            {
                return false;
            }
        }
 
        public bool TryGetValue(string key, out object value)
        {
            return appDictionary.TryGetValue(key, out value);
        }
 
        public ICollection<object> Values
        {
            get { return appDictionary.Values; }
        }
 
        public object this[string key]
        {
            get
            {
                return appDictionary[key];
            }
            set
            {
                appDictionary[key] = value;
                Save();
            }
        }
 
 
        public void Add(KeyValuePair<stringobject> item)
        {
            appDictionary.Add(item.Key, item.Value);
        }
 
        public void Clear()
        {
            appDictionary.Clear();
            Save();
        }
 
        public bool Contains(KeyValuePair<stringobject> item)
        {
            return appDictionary.ContainsKey(item.Key);
        }
 
        public void CopyTo(KeyValuePair<stringobject>[] array, int arrayIndex)
        {
            throw new NotImplementedException();
        }
 
        public int Count
        {
            get { return appDictionary.Count; }
        }
 
        public bool IsReadOnly
        {
            get { return false; }
        }
 
        public bool Remove(KeyValuePair<stringobject> item)
        {
            return appDictionary.Remove(item.Key);
        }
 
        public IEnumerator<KeyValuePair<stringobject>> GetEnumerator()
        {
            return appDictionary.GetEnumerator();    
        }
 
        IEnumerator IEnumerable.GetEnumerator()
        {
            return appDictionary.GetEnumerator();
        }
 
        #endregion
    }