dotnet thoughts 

a dotnet developer's technical blog

Working with datagridview in WPF

When I started working in WPF, the issue found in WPF is that there is no DataGrid. And I couldn’t find any alternative for that. But after few days one of my colleague said there is an option to do it. And it is like setting a View of the Listview control.

So here is the XAML code for a grid like this

<listview Name="MyListView">
</listview><listview .ItemsSource>
<binding Source="{StaticResource AddressData}" Mode="OneWay" />
</listview>
<listview .View>
<gridview AllowsColumnReorder="True">
<gridviewcolumn Header="Name" Width="175" >
</gridviewcolumn><gridviewcolumn .DisplayMemberBinding>
<binding Path="Name" />
</gridviewcolumn>

<gridviewcolumn Header="Address" Width="200">
</gridviewcolumn><gridviewcolumn .DisplayMemberBinding>
<binding Path="Address" />
</gridviewcolumn>

<gridviewcolumn Header="Email" Width="100">
</gridviewcolumn><gridviewcolumn .DisplayMemberBinding>
<binding Path="Email" />
</gridviewcolumn>

</gridview>
</listview>

You can also use the “GridViewColumn.CellTemplate” for modifing the display of the controls. Here I am displaying a checkbox, using a “IsUserExists” boolean property.

<gridviewcolumn Header="?" Width="Auto" >
</gridviewcolumn><gridviewcolumn .CellTemplate>
<datatemplate>
<checkbox IsChecked="{Binding Path=IsUserExists}" />
</datatemplate>
</gridviewcolumn>

You can also create events too, like this

<style x:Key="ListViewItemEvent" TargetType="{x:Type ListViewItem}">
<eventsetter Event="MouseDoubleClick" Handler="lstvMouseDoubleClickEvent" />
</style>

And assign the “ListViewItemEvent” style to the ItemStyle property of the listview. And in the code you will get the ListviewItem object as sender.

Sub lstvMouseDoubleClickEvent(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
Dim oListViewItem As ListViewItem = CType(sender, ListViewItem)
Dim oAddress As Address = CType(oListViewItem.Content, Address)
'Binding code...
End Sub

I got the code of event setting from here

Context menus in WPF

You can create context menus in the WPF by using Context menu tag. You can only create the context menu with some controls, if you are using Context menu in design tie using XAML. Otherwise you will get an error like this “‘ContextMenu’ cannot have a logical or visual parent” in Runtime.

Creating context menus for Textbox. – Normally textbox comes with a Context menu, contains 3 actions cut, copy and paste. And based on the situations it will be enabled / disabled. I got the job to implement new cotext menu instead of these 3, the textbox is a part of a user control.


<Grid.Resources>
<Image x:Key="MenuItem" Source="C:\Icon1.ico" />
<Image x:Key="MenuItem1" Source="C:\Icon2.ico" />
</Grid.Resources>

<TextBox Name="txtName">
<TextBox.ContextMenu>
<ContextMenu>
<MenuItem Header="Menu Item 1" Icon="{StaticResource MenuItem1}" />
<MenuItem>
<MenuItem.Header>
<TextBlock Foreground="Blue" FontWeight="Bold">
<Underline>Menu Item2</Underline>
</TextBlock>
</MenuItem.Header>
</MenuItem>
<MenuItem Header="Menu Item 3" />
<Separator/>
<MenuItem Header="Menu Item 4" Icon="{StaticResource MenuItem}" IsEnabled="False" InputGestureText="Ctrl+Alt+Q" />
<MenuItem Header="Menu Item 5" IsCheckable="True" IsChecked="True" />
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>

Screenshot 2 : Context menu from XAML Markup.


You can also create Context menus in Runtime using the code


Dim oContextMenu As New ContextMenu
oContextMenu.Items.Add(New MenuItem With {.Header = "Runtime Menu 1"})
'I don't know this is the right way to access resources. I added name attribute to Grid, to access the Grid in the code.
oContextMenu.Items.Add(New MenuItem With {.Header = "Runtime Menu 2", .Icon = MyGrid.Resources("MenuItem")})
oContextMenu.Items.Add(New MenuItem With {.Header = "Runtime Menu 3", .IsEnabled = False})
oContextMenu.Items.Add(New Separator)
oContextMenu.Items.Add(New MenuItem With {.Header = "Runtime Menu 4", .IsCheckable = True, .IsChecked = True})
Me.txtName.ContextMenu = oContextMenu

Screenshot 2 : Context menu from Code behind.

Note : While working with this issue, I found some problem with Resources, if you are using the same image for two menu items, you need to create the entry in the resources twice, other wise it will display only second one.

Menu Icons in WPF

As part of my WPF experiments, in the last one I posted how to Add shortcuts in WPF menus. I this post I am adding Icons to WPF menu.

Upto .Net 2.0, to display icons in menus, we need add a menu strip to the form, right click on the menuitem and select “Set Image”, it will popup a window, where we can select the Image and it will automatically updated in menu.
But in WPF there is not “Set Image” menu item in the right click and the properties window, it is a Textbox. After few googling I found a solution.

<Grid>
<Grid.Resources>
<!-- Here I am loading all the Images -->
<Image x:Key="folder" Source="Icons/folder.ico" Height="16" Width="16" />
<Image x:Key="Open" Source="Icons/Open16x16.ico" Height="16" Width="16" />
<Image x:Key="Save" Source="Icons/Save16x16.ico" Height="16" Width="16" />
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>       
<Menu Grid.Row="0" >
<MenuItem Header="_File">
<MenuItem Header="_Open" Icon="{StaticResource Open}" />
<MenuItem Header="Open _Folder" Icon="{StaticResource folder}" />
<Separator />
<MenuItem Header="_Save" Icon="{StaticResource Save}" />
</MenuItem>
</Menu>
<Image Grid.Row="1" />
</Grid>

Screenshot, which displaying Icons on menu items

Please not if you not set the Height and Width properties, in Resources, the Icons will grow automatically, to the full window ;)

Update : You can set the application Icon or the Window Icon by simple markup like this

<window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:winfx="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Icons in Menu" Height="300" Width="300" Icon="Icons/folder.ico">

Shortcuts keys in WPF Menu

From the last few days I was searching for adding shortcut keys to WPF menu items. I didn’t see any direct method over there in Visual Studio. But after some googling I found some ways.

  1. Using access keys, like ALT+key – This is like the old Hot key implementation, using &, but & will not work in WPF instead of this we need to use “_”
    <MenuItem Header="_Open" />
    But these way you can use ALT+ key as the shortcut key
  2. Using code, like for displaying the shortcut key in the Menu item you can use “InputGestureText”e; property of menu item and using the code, need to capture the key press. I don’t know is it possible or not, I wasn’t checked this method, but the shortcut will appear on the menu :)
    <MenuItem Header="_Open" InputGestureText="Ctrl+O" />
  3. The final way is using CommandBindings. I found this way is better compare to the previous methods, and it is an easy way.
    1. In the markup create the command Bindings using Command Collections.
      <CommandBinding Command="ApplicationCommands.Open" CanExecute="CommandCanExecute" Executed="CommandExecuted" />
      <CommandBinding Command="ApplicationCommands.Close" CanExecute="CommandCanExecute" Executed="CommandExecuted" />
    2. In the code implement the event Handlers.
      Sub CommandExecuted(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)
      'Add the commands to be executed.
      If e.Command.Equals(ApplicationCommands.Open) Then
      MessageBox.Show("Open Menu item clicked")
      ElseIf e.Command.Equals(ApplicationCommands.Close) Then
      MessageBox.Show("Close menu item clicked")
      End If
      End Sub
      Sub CommandCanExecute(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs)
      e.CanExecute = True 'I am always returning true, based on this the menu item will enabled / disabled
      End Sub
    3. Assign the Commands to the Command property of our menu items. <MenuItem Command="ApplicationCommands.Open" >
      <Separator />
      <MenuItem Command="ApplicationCommands.Close" />

Compile it run it. You will see “Ctrl + O” added to the right side Open menu item.

You can see Ctrl + O added into the Open Menu item(Screenshot)

Object Initializers in VB.Net

In my last post I have used a special syntax for creating instance of Person Class.
VB.Net

Dim p as New Person With {.Name = “Person1″, .Age = 20}

C#

Person p = New Person {Name = “Person1″, Age = 20};

Which is equivalent to
VB.Net

Dim oPerson as new Person
oPerson.Name = "Person1"
oPerson.Age = 20

C#

Person oPerson = new Person();
oPerson.Name = "Person1";
oPerson.Age = 20;

This is another new feature introduced in VB.Net 9.0, called Object Initializers. You can get more information about this in MSDN. Actually I am planning to write a post on the feature newly available in VB.Net 9.0

Links : VB.Net and C#

Older Posts »