Sunday, April 25, 2010

Showing a button in Xceed DataGridView column

0 comments

image

Want to have a button in a Grid?

3 things are here:

  1. Grid definition
  2. column definition
  3. Template for button

 

 

1. Grid: <xcdg:DataGridControl x:Name="mGrid" />

2. Columns:

<xcdg:DataGridControl.Columns>
<
xcdg:Column FieldName="MyThing" Title="Things"
VisiblePosition="0"/>
<xcdg:Column FieldName="." Title="Action" MinWidth="100" MaxWidth="200" CellContentTemplate="{StaticResource ActionButtons}"/>
</
xcdg:DataGridControl.Columns>



3. and the actual template:<UserControl.Resources>

   <
DataTemplate x:Key= "ActionButtons">

     <
StackPanel Orientation="Horizontal">

       <
Button Content="{BindingNextAction}" DataContext="{Binding}" IsEnabled="{Binding Enabled}"Click="NextAction_Click">

     </
StackPanel>

   </
DataTemplate>

</
UserControl.Resources>




 


Wednesday, April 21, 2010

LINQ Examples

0 comments

Some basic LINQ examples for queering into collections.LINQ extension here: msdn

var newThings = from thing in allThings
                 where thing.Stamp >= dateYesterday
                 select thing;

extracting different collection structure:

IEnumerable<string> ids = mUsers.Select(u => u.GUID);

getting unique ones:

IEnumerable<string> uniqueIds = ids.Distinct<string>();

finding one:

IEnumerable<User> users = mUsers.Where(u => u.GUID == thatGUID);

flattens the resulting sequences into one sequence

IEnumerable<Locations> places = mUsers.SelectMany(u => u.Locations);

Sunday, April 18, 2010

Flattening structure for Hierarchical display

0 comments

image

I’ve been dealing before with HierarchicalDataTemplate where one Template references another one for 2 level hardcoded data structure. What about data that recursively references several types of “children”. Plus each type shows itself uniquely. How to visualize this ?

See tree screenshot as an example. In this example we have 3 data types: Drive, Folder, Files. Drive is a top level. Folder references Folder and Files.

Here is an overview of relationships between TreeView and Data Templates.

We need 2 things: DataTemplateSelector and “HierarchyConverter”.

HierarchyConverter is IValueConverter. HierarchyConverter parses through given object and returns “Children”, one level after another.

DataTemplateSelector returns a HierarchicalDataTemplate based on given object Type. Similar object types that were handled in HierarchyConverter. DataTemplateSelector is assigned to ItemTemplateSelector.

Each data type has an appropriate HierarchicalDataTemplate. Top level data template(Drive in our example) engages DataTemplateSelector. And all data types engage HierarchyConverter.

Top Level Template:

<HierarchicalDataTemplate x:Key="DriveTemplate"
ItemTemplateSelector="{StaticResource TreeTemplateSelector}"
ItemsSource="{Binding Converter={StaticResource HierarchyConverter}}">





The rest of levels follow similar format:

<HierarchicalDataTemplate x:Key="FolderTemplate"  DataType="{x:Type Framework:Folder}"

                       ItemsSource="{Binding Converter={StaticResource HierarchyConverter}}">
                                                           



And to start it with your favorite Tree View:       <my:CustomTreeView Name="MyTree" ItemTemplate="{StaticResource DriveTemplate}"             


Let’s try to summarize data flow here. TreeView accepts data and streams to DriveTemplate. DriveTemplate sticks around until Folder in means of HierarchyConverter, while engaging TemplateSelector. At that time, different DataTemplates are activated which again engage recursive nature of HierarchyConverter.


Friday, April 16, 2010

WPF Threads: Dispatcher

0 comments

Apparently WPF framework became a bit smarter in terms of threads comparing to Windows Forms.There is Dispatcher.

Now you might be forced to queue UI actions like this:

Dispatcher.Invoke(DispatcherPriority.Send, new ThreadStart(() =>
{
MyTree.SelectedItem = folderToEdit;
}));





Another example for single no parameter function:



Dispatcher.BeginInvoke(new Action(() =>
{

Wednesday, April 14, 2010

WPF UI Automation

0 comments

Some things to be aware of when engaging Microsoft Automation.

1. Run UI SPY to browse around your app structure.

2. Expand Controls that do not support UI Automation

3. Provide “good” AutomationProperties.AutomationId for controls.

Why would you expose UserControl for Automation? Some third party user controls do not support automation. Or you might want to expose custom UI structure that tailored towards desired Testing.

How to expose UserControl and see it in UI Spy ?

Something like that:

image

 

filling AutomationId
  1. <Style x:Key="AutomationEnabledRibbonGroup" TargetType="ribbon:Group">
  2.     <Style.Setters>
  3.       <Setter Property="AutomationProperties.AutomationId" Value="{Binding RelativeSource={RelativeSource Self}, Path=Label}" />
  4.     </Style.Setters>
  5.   </Style>
  6.  
  7.     <Style x:Key="AutomationEnabledButton" TargetType="{x:Type Button}"BasedOn="{StaticResource {x:Type Button}}">
  8.     <Style.Setters>
  9.       <!-- Buttons without Name/x:Name have no AutomationId, this setter initializes id with the button's text  -->
  10.       <Setter Property="AutomationProperties.AutomationId" Value="{Binding RelativeSource={RelativeSource Self}, Path=Content}" />
  11.     </Style.Setters>
  12.   </Style>
  13.  
  14.   <Style x:Key="AutomationEnabledListBoxItem" TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource {x:Type ListBoxItem}}">
  15.     <Setter Property="AutomationProperties.AutomationId" Value="{Binding RelativeSource={RelativeSource Self}, Path=Content}" />
  16.   </Style>

Thursday, April 8, 2010

Member Variables in XAML?

0 comments

image

What ResourceDictionary is for ? It’s a descriptive way of defining “member variables” in XAML itself. Similar to member variables defined in good old Class definitions.

Define it in the XAML through means of Resources. Get it back in C# with FindResource.

WPF requires Data Structure

0 comments

I’ve been working recently with some legacy architecture which is heavy xml based. There are several remotely distributed servers. Whole business model is exchanged in means of xml streams. No data structures. Now Go and visualize it in WPF UI. Nothing to bind to.

What I end up doing over and over again is creating Data Structures internally from xml streams(AltovaXML helps). This way UI can bind to something.

WPF loves Data Structure.

My selfish preferences: Create Classes for Data. Rely on them. Pass them in interfaces. Please no text/xml streams.

Tuesday, April 6, 2010

Creating MenuItems dynamically

0 comments

image This approach is for creating context menu programmatically in .NET3.5/WPF. This is useful when menu structure is variable and dependable.

First there is “MyMenuItem” data structure. It maps to single imagemenu item. You create these objects, link together, and pass over to MenuManager. MenuManager would in turn convert them into real windows MenuItems.

 

 

Client Example:

List<MenuItem> menuItems = mMenuManager.Build(new List<MyMenuItem>() { 
new MyMenuItem() { Label = "1111"},
new MyMenuItem() { Label = "1111"},
new MyMenuItem() { Label = "1111"},
});

foreach (MenuItem menuItem in menuItems)
MyContextMenu.Items.Add(menuItem);






Download MenuManager.cs file here:




using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Media.Imaging;

namespace sergeymalyan.blogspot.com
{
public class MyMenuItem
{
public string Label { get; set; }
public Image ImageIcon { get; set; }
public object Tag { get; set; }

public List<MyMenuItem> DeeperItems
{
get { return mDeeperItems; }
set { mDeeperItems = new List<MyMenuItem>(value); }
}

private List<MyMenuItem> mDeeperItems = new List<MyMenuItem>();
}

/// <summary>
/// Created by Sergey Malyan
/// </summary>
class MenuManager
{
#region events
public delegate void MenuClickedDel(MyMenuItem item);
public event MenuClickedDel MenuClicked;

#endregion

public List<MenuItem> Build(List<MyMenuItem> itemsIn)
{
List<MenuItem> items = new List<MenuItem>();

foreach (MyMenuItem item in itemsIn)
{
items.Add(Traverse(item));
}


return items;
}

private MenuItem Traverse(MyMenuItem item)
{
MenuItem menu = new MenuItem();
try
{
menu.Header = item.Label;

if (item.ImageIcon != null)
{
item.ImageIcon.Width = item.ImageIcon.Height = 16;
menu.Icon = item.ImageIcon;
}


foreach (MyMenuItem item2 in item.DeeperItems)
{
menu.Items.Add(Traverse(item2));
}

menu.Tag = item;

if (item.DeeperItems.Count == 0)
{
menu.Click += new System.Windows.RoutedEventHandler(menu_Click);
}

}
catch (Exception ex)
{
throw;
}

return menu;
}

private void menu_Click(object sender, System.Windows.RoutedEventArgs e)
{
MyMenuItem item = ((MenuItem)sender).Tag as MyMenuItem;

if (MenuClicked != null)
MenuClicked(item);

}
}
}



Thursday, April 1, 2010

how to instantiate a class from xml

0 comments

also known as xml deserialzing a class from a file.

image

 

Feeded xml data has to match the fields. For reading in, see this post.

saving class instance to a file

0 comments

also known as serializing a class to a file.

image

So. That’s it. Go check the file context for xml formatted data.