Live Chat Icon For mobile
Live Chat Icon

WPF FAQ

Find answers for the most frequently asked questions
Expand All Collapse All

First create a custom DataTemplate that uses adjacent TextBlocks to render values from 2 different columns next to each other.


<Window.Resources>  
            <DataTemplate x:Key='lbItemsTemplate'>   
                <StackPanel FlowDirection='LeftToRight'  Orientation='Horizontal'>   
                    <TextBlock Text='{Binding Path=Title}'></TextBlock>  
                    <TextBlock Text=' \ '></TextBlock>  
                    <TextBlock Text='{Binding Path=Summary}'></TextBlock>  
                </StackPanel>  
            </DataTemplate>  
</Window.Resources>  

Above, Title and Summary are the two columns.

Then specify this template in your ListBox:


<ListBox x:Name='ListView1' ItemTemplate='{StaticResource lbItemsTemplate}' ItemsSource='{StaticResource InventoryData}'>   
</ListBox>  
Permalink

The following code shows how the content template can be created and applied to a content control.

[XAML]
<DataTemplate x:Key='template1'>
  <TextBlock Text='{Binding}' FontSize='12' FontWeight='Bold' TextWrapping='Wrap'></TextBlock>
</DataTemplate>

The above code can be applied as follows.

[XAML]

<Button ContentTemplate='{StaticResource template1}' Content='Click'>
Permalink

Items can be displayed horizontally using the ItemsPanel property of the ListBox.

The following lines of code are used to display the items horizontally.

[XAML]

<ListBox Height='40' Width='50'>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
            	<StackPanel Orientation='Horizontal'/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
      <ListBoxItem>1 ITEM 1</ListBoxItem>
<ListBoxItem>2 ITEM 2</ListBoxItem>
<ListBoxItem>3 ITEM 3</ListBoxItem>
</ListBox>
Permalink

This can be done using the code given below.

[XAML]

        <Page xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
    xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' >
            <!-- For demonstration purposes, animate ProgressBar.Value -->
            <Page.Triggers>
                <EventTrigger RoutedEvent=’Page.Loaded’>
                    <BeginStoryboard>
                        <Storyboard TargetName=’ProgressBar’ TargetProperty=’Value’>
                            <DoubleAnimation From=’0’ To=’100’ Duration=’0:0:1’ />
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Page.Triggers>
            <Grid Height='30' >
                <ProgressBar Name=’ProgressBar’ />
                <Viewbox>
                    <TextBlock>
        <TextBlock.Style>
          <Style TargetType=’TextBlock’>
            <!-- Make the text 'Loading ...' by default-->
            <Setter Property=’Text’ Value=’Loading ...’ />          
            <!-- But when ProgressBar.Value is 100, change the text to 'Complete' -->
            <Style.Triggers>
              <DataTrigger Binding=’{Binding Value, ElementName=ProgressBar}’ Value=’100’>
                <Setter Property=’Text’ Value=’Complete’ />
              </DataTrigger>
            </Style.Triggers>
          </Style>
        </TextBlock.Style>
      </TextBlock>
                </Viewbox>
            </Grid>
        </Page>

Permalink
[XAML]
  
<StackPanel MouseLeftButtonDown='HandleMouseInput' Margin='5'>
            <StackPanel.Resources>
                <!--Base TextBox Style-->
                <Style x:Key='TextBoxBaseStyle' TargetType='{x:Type TextBox}'>
                    <Setter Property='FontSize' Value='20'/>
                    <Setter Property='Margin' Value='5'/>
                </Style>
                <!--Simplified TextBox Style with template & necessary bindings.-->
                <Style
        x:Key='BasicTextBox'
        TargetType='{x:Type TextBox}'
        BasedOn='{StaticResource TextBoxBaseStyle}'>
                    <Setter Property='Template'>
                        <Setter.Value>
                            <ControlTemplate TargetType='{x:Type TextBox}'>
                                <Border
                BorderBrush='{TemplateBinding BorderBrush}'
                BorderThickness='{TemplateBinding BorderThickness}'
                Background='{TemplateBinding Background}'>
                  <TextBlock
                  Margin='3.85,2,3.85,2'
                  Text='{TemplateBinding Text}'
                  TextDecorations='{TemplateBinding TextDecorations}'/>
              </Border>
                   </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                    <Setter Property='Focusable' Value='false'/>
                </Style>
            </StackPanel.Resources>
            <TextBox Width='100' Height='30' Style='{StaticResource BasicTextBox}'></TextBox>
    </StackPanel>

The events of the above code are given below.

[C#]

        void HandleMouseInput(object sender, MouseEventArgs args)
        {
            TextBox tb = args.Source as TextBox;
            if (tb == null)
                return;
            if (ActiveTextBox == null)
                Activate(tb);
            else
                Deactivate(ActiveTextBox);
        }

        //Deactivates the active TextBox if the Enter
        // or ESC key is pressed.

        void HandleKeyInput(object sender, KeyEventArgs args)
        {
            TextBox tb = args.Source as TextBox;
            if (tb != null &&
                  (args.Key == Key.Return || args.Key == Key.Escape))
                Deactivate(tb);
        }

        //Deactivate the Textbox the active TextBox.
        void HandleLostFocus(object sender, EventArgs args)
        {
            TextBox tb = sender as TextBox;
            if (tb != null)
                Deactivate(tb);
        }

        //Activate the TextBox by applying the base style
        //(thereby removing the basic style.)  Set focus, select
        //all the content & invalidate the visual.
        //Also, dynamically add handlers for losing focus and
        //handling key input.

        void Activate(TextBox tb)
        {
            tb.Style = (Style)tb.FindResource('TextBoxBaseStyle');
            tb.Focus();
            tb.SelectAll();
            tb.InvalidateVisual();
            tb.LostFocus += new RoutedEventHandler(HandleLostFocus);
            tb.KeyDown += new KeyEventHandler(HandleKeyInput);
            ActiveTextBox = tb;
        }

        //Deactivate the TextBox by applying the Basic style.
        //Remove the event handlers.

        void Deactivate(TextBox tb)
        {
            tb.Style = (Style)tb.FindResource('BasicTextBox');
            tb.LostFocus -= new RoutedEventHandler(HandleLostFocus);
            tb.KeyDown -= new KeyEventHandler(HandleKeyInput);
            ActiveTextBox = null;
        }
Permalink

The most common binding scenarios involve the data getting updated from the source to the target. But, in some cases, the source has to be updated when changes are made by the users in the target. Such cases can be defined using the ‘BindingModes’ of the Binding markup extension class. ‘BindingModes’ is an enumeration property and it takes the following values.

1. OneWay – The target is updated whenever the source is updated.

2. TwoWay – A change to either the target or source updates the other.

3. OneWayToSource – It is an opposite of OneWay. The source is updated whenever the target value changes.

4. OneTime – It is similar to OneWay except that the changes to the source are also not reflected in the target. The target contains the value of the source when Binding was initiated.

Permalink

Every FrameworkElement can be associated with a DataContext which will be used as the default data source during binding, if no other data source is specified in the binding code. Also, the children of this FrameworkElement auotmatically inherit this setting. This helps having to repeatedly specify this data source as the source of a binding, thereby letting you simplify the binding code.

The following code snippet is an example of implicit datasource using DataContext.

[XAML]

<StackPanel x:Name='Class' DataContext='{StaticResource student}'>
<Label x:Name='studcount' Content='{Binding Path=Count}'/>
<ListBox x:Name='Studname' DisplayMemberPath='Name' ItemsSource='{Binding}'/>
</StackPanel>

Permalink

When you declare elements inside the ControlTemplate, use the ‘Name’ of each control for identifying it from the outside. We can then use the ‘FindName’ function for finding the resource.

An example shown below is for accessing the TextBlock of a button.

[XAML]

<Button Background='LightGoldenrodYellow'>
	<Button.Style>
		<Style TargetType='Button'>
		<!--Set to true to not get any properties from the themes.-->
			<Setter Property='OverridesDefaultStyle' Value='True'/>
			<Setter Property='Template'>
			<Setter.Value>
				<ControlTemplate TargetType='Button'>
				<Grid>
				<Ellipse Name='innerEllipse' Fill='{TemplateBinding Background}'/>
					<ContentPresenter HorizontalAlignment='Center'
                                  			VerticalAlignment='Center'/>
				</Grid>
				</ControlTemplate>
			</Setter.Value>
			</Setter>
		</Style>
	</Button.Style>
</Button>

[C#]
// From inside the custom Button type:
Ellipse ellipse = this.Template.FindName('innerEllipse', this) as Ellipse;

Permalink

WPF enables users to apply animations to objects by applying animations on properties. For a property to have animation capabilities, it should have the following requirements.

  • The property should be a dependency property.
  • It must belong to a class that inherits from the DependencyObject class and implements the IAnimatable interface.
  • There must be a compatible Animation type available for the property. For e.g. the Double type property can be animated using the DoubleAnimation. Similarly, the property to be animated should contain the corresponding animation type.
  • Permalink

    Lights are similar to lights in real life. Light objects are used to illuminate a part of a scene. Lights can be used to create shadow effects. In a 3D scene at least one light has to be added to make the scene visible. WPF has four different types of lights with unique functionalities.

    The following are the types of light available in WPF.

  • AmbientLight – provides uniform lighting to all the objects in a 3D scene.
  • DirectionalLight – It is like a distant light source. It does not have a location but has a direction.
  • PointLight – It illuminates like a nearby light source. It has a location and provides light effect from the location and objects in the scene are illuminated based on the location and position of the point light.
  • SpotLight – It is similar to a pointlight. It provides illumination in a cone shape. The ‘InnerConeAngle’ and ‘OuterConeAngle’ properties determine the illumination of the objects in the 3D scene.
  • Permalink

    This can be done as follows.

    [XAML]
    
    <Style x:Key='ContentCtrl' TargetType='ContentControl'>
        <Setter Property='Background' Value='Red'/>
        <Setter Property='Foreground' Value='Green'/>
        <Setter Property='FontSize' Value='20'/>
        <Setter Property='FontWeight' Value='Bold'/>
        <Setter Property='Template'>
            <Setter.Value>
                <ControlTemplate TargetType='ContentControl'>
                    <Grid>
                        <Ellipse Width='{TemplateBinding Width}' Height='{TemplateBinding Width}' Fill='{TemplateBinding Background}'/>
                        <ContentPresenter VerticalAlignment='Center' HorizontalAlignment='Center'/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
    ...
    
    <ContentControl Width='75' Height='100' Style='{StaticResource ContentCtrl}' Content='Hello'/>
    
    Permalink

    CommandBinding can be added to a window using markup. Note that in XAML, the CommandBindingCollection is not declared in the markup as an element and the collection object is inferred by the type that the property takes and you populate the property element with one or more CommandBinding elements.

    [XAML]
    
    <Window.CommandBindings>
      <CommandBinding Command='ApplicationCommands.Open'
                      Executed='OpenCmdExecuted'
                      CanExecute='OpenCmdCanExecute'/>
    </Window.CommandBindings>
    
    Permalink

    Here is how you would access a Canvas.Left extended property for example:

    
            <DataTemplate x:Key='MyTemplate1'>
                <Path Data='{Binding Geometry}'>
                    <Path.RenderTransform>
    		<!-- The Item property returns a visual hosted inside the Canvas -->
                        <RotateTransform Angle='60' CenterX='{Binding Item.(Canvas.Left)}' 
                                         CenterY='{Binding Item.(Canvas.Top)}' 
                                         >
                        </RotateTransform>
                    </Path.RenderTransform>
                </Path>
            </DataTemplate>
    
    Permalink

    Perhaps you want your two ‘TextBlock’ elements to share some property values such as the FontFamily and the centered HorizontalAlignment, but you also want the text ‘My Pictures’ to have some additional properties. You can do that by creating a new style that is based on the first style, as shown here.

    [XAML]
    
    <Window.Resources>
    
    ...
    
    <!--A Style that extends the previous MyBaseStyle Style-->
    <!--This is a 'named style' with an x:Key of MyDerivedStyle-->
    <Style BasedOn='{StaticResource {x:Type MyBaseStyle}}'
           TargetType='TextBlock'
           x:Key='MyDerivedStyle'>
      <Setter Property='FontSize' Value='26'/>
      <Setter Property='Foreground'>
      <Setter.Value>
          <LinearGradientBrush StartPoint='0.5,0' EndPoint='0.5,1'>
            <LinearGradientBrush.GradientStops>
              <GradientStop Offset='0.0' Color='#90DDDD' />
              <GradientStop Offset='1.0' Color='#5BFFFF' />
            </LinearGradientBrush.GradientStops>
          </LinearGradientBrush>
        </Setter.Value>
      </Setter>
    </Style>
    
    
    Permalink

    The following example shows how you can set an attached property in code.

    [C#]
    
    DockPanel myDockPanel = new DockPanel(); 
    CheckBox myCheckBox = new CheckBox(); 
    myCheckBox.Content = 'Hello'; 
    myDockPanel.Children.Add(myCheckBox); 
    DockPanel.SetDock(myCheckBox, Dock.Top);  
    
    
    Permalink

    Most of UI Elements in WPF can contain only a single child element, therefore, when you add a control to a button, an error stating that the control has a child and only one child can be added to the control is generated. To overcome this error add layouts like StackPanel inside the control and add multiple controls inside that StackPanel.

    The following code snippet will cause the error mentioned above.

    [XAML]
    
    <Button Height='100'>
                <RadioButton Content='Button1' />
                <RadioButton>Button 2</RadioButton>>
    </Button>
    

    A StackPanel can be used inside the button to have multiple controls inside the button.

    The following lines of code can be used to overcome the error.

     [XAML]
    <Button Height='100'>
    	<StackPanel Orientation='Horizontal'>
            <RadioButton Content='Button1'/>
    		<RadioButton>Button 2</RadioButton>
        </StackPanel>
    </Button>
    
    Permalink

    XAML is an extensible markup language based on XML. XAML can be thought of as a declarative script for creating .NET 3.0 UI. It is particularly used in WPF as a user interface markup language to define UI elements, data binding, eventing and other features. It is also used in Windows Workflow Foundation (WF), in which the workflows themselves can be defined in XAML code.

    Permalink

    Windows Presentation Foundation (WPF) is the presentation subsystem feature of the .NET Framework 3.0. It is pre-installed in as a part of Windows Vista, It is also available for installation on Windows XP SP2 and Windows Server 2003. It supports the rich User Experiences (UX) that have been made possible by advances in hardware and technology since the GDI based UI architecture was initially designed in the 1980’s.

    Also refer to the separate section on XAML in this FAQ

    Permalink

    This example creates a ProgressBar and uses an ’animation’ to simulate the progress of an operation.

    [XAML]
    
    <StatusBar Name='sbar' 
               VerticalAlignment='Bottom' Background='Beige' >
    
      <StatusBarItem>
        <TextBlock>Downloading File</TextBlock>
      </StatusBarItem>
      <StatusBarItem>
        <ProgressBar Width='100' Height='20'
                     Name='progressBar1'>
          <ProgressBar.Triggers>
            <EventTrigger RoutedEvent='ProgressBar.Loaded'>
              <BeginStoryboard>
                <Storyboard>
                  <DoubleAnimation
                    Storyboard.TargetName='progressBar1' 
                    Storyboard.TargetProperty='Value'
                    From='0' To='100' Duration='0:0:5'  />
                </Storyboard>
              </BeginStoryboard>
            </EventTrigger>
          </ProgressBar.Triggers>
        </ProgressBar>
      </StatusBarItem>
      <StatusBarItem>
        <Separator/>	
      </StatusBarItem>
      <StatusBarItem>
        <TextBlock>Online</TextBlock>
      </StatusBarItem>
      <StatusBarItem HorizontalAlignment='Right'>
        <Image Source='images\help.bmp' Width='16' Height='16'/>
      </StatusBarItem>
    </StatusBar>
    
    
    Permalink

    x:Code is a directive element defined in XAML. An x:Code directive element can contain inline programming code. The code that is defined inline can interact with the XAML on the same page. The following example illustrates inline C# code. Notice that the code is inside the x:Code element and that the code must be surrounded by <CDATA[…]]> to escape the contents for XML, so that an XAML processor (interpreting either the XAML schema or the WPF schema) will not try to interpret the contents literally as XML.

    [XAML]
    
    <Page
      xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
      xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
      x:Class='MyNamespace.MyCanvasCodeInline'
    >
      <Button Name='button1' Click='Clicked'>Click Me!</Button>
      <x:Code><![CDATA[
        void Clicked(object sender, RoutedEventArgs e)
        {
            button1.Content = 'Hello World';
        }
      ]]></x:Code>
    </Page>
    
    Permalink

    An ‘attached’ property is a concept defined by Extensible Application Markup Language (XAML). It is intended to be used as a type of global property that can be set on any object. In Windows Presentation Foundation (WPF), attached properties are typically defined as specialized forms of dependency properties that do not have the conventional ‘wrapper’ property.

    This example shows how to ’register’ an attached property and provide public accessors so that you can use the property in both Extensible Application Markup Language (XAML) and code. Attached properties are a syntax concept defined by Extensible Application Markup Language (XAML). Most of the attached properties for WPF types are also implemented as dependency properties. You can use dependency properties on any ’DependencyObject’ types.

    [C#]
    public static readonly DependencyProperty IsBubbleSourceProperty = DependencyProperty.RegisterAttached(
      'IsBubbleSource',
      typeof(Boolean),
      typeof(AquariumObject),
      new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender)
    );
    public static void SetIsBubbleSource(UIElement element, Boolean value)
    {
      element.SetValue(IsBubbleSourceProperty, value);
    }
    public static Boolean GetIsBubbleSource(UIElement element)
    {
      return (Boolean)element.GetValue(IsBubbleSourceProperty);
    }
    
    
    Permalink

    Embedded XAML Resources

    Several WPF assemblies come with embedded XAML resources, like template definitions, style definitions, etc. And it’s often very useful to take a look at these embedded XAML to understand the structure of a control and thereby making it easier to customize it’s UI in your applications, if necessary.

    The best way to take a look at these embedded XAML resources is to use the Reflector tool with the BAML Viewer plugin.

    Reflector + BAML Viewer

    Reflector is a popular Free tool available since the early days of .NET to help you take a deeper look at the source and resources comprising a .NET assembly. Reflector can be downloaded here:

    .NET Reflector

    Here is a thumbnail view of the Reflector tool:

    Once you install the Reflector, download the BAML Viewer plug-in from:
    BAML Viewer – Reflector Plugin

    The plug-in is a single dll called Reflector.BamlViewer.dll. Put this dll next to the Reflector.exe and follow these steps to add the plug-in to the Reflector:
    a) In the Reflector tool, select the View/Add Ins… menu item.
    b) In the ‘Add Ins’ dialog box, Add the above dll as an ‘add-in’. This will include a new ‘Tools/BAML Viewer’ menu item in the Reflector.
    c) Then open a WPF assembly (or Syncfusion assembly) that usually contains a BAML resource, like PresentationFramework.Aero.dll (usually found under ‘%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.0\PresentationFramework.Aero.dll’)
    d) Then select the ‘Tools/BAML Viewer’ menu item. This will open a new ‘BAML Viewer’ view showing the embedded XAML in the above assembly.

    Here is a screenshot of the BAML Viewer showing the embedded XAML in the PresentationFramework.Aero.dll:

    You can similarly view XAML resources embedded into Syncfusion assemblies.

    Permalink

    You can do so by first defining a DataTemplate for the corresponding columns as follows. Sample code can be seen with better formatting in this thread (ListView Column ToolTip)

    [XAML]
    <Page xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
          xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
        <StackPanel>
            <StackPanel.Resources>
                <DataTemplate x:Key='nameTemplate'>
                    <TextBlock Text='{Binding Name}'  Margin='-6,0'>
                        <TextBlock.ToolTip>
                            <ToolTip>
                                <TextBlock Foreground='Green' Text='{Binding Name}'/>
                            </ToolTip>
                        </TextBlock.ToolTip>
                    </TextBlock>
                </DataTemplate>
                <DataTemplate x:Key='namespaceTemplate'>
                    <TextBlock Text='{Binding Namespace}'  Margin='-6,0'>
                        <TextBlock.ToolTip>
                            <ToolTip>
                                <TextBlock Foreground='Green' Text='{Binding Namespace}'/>
                            </ToolTip>
                        </TextBlock.ToolTip>
                    </TextBlock>
                </DataTemplate>
            </StackPanel.Resources>
            <ListView>
                <ListView.ItemContainerStyle>
                    <Style TargetType='ListViewItem'>
                        <Setter Property='HorizontalContentAlignment' Value='Stretch'/>
                        <Setter Property='VerticalContentAlignment' Value='Stretch'/>
                    </Style>
                </ListView.ItemContainerStyle>
                <ListView.View>
                    <GridView>
                        <GridViewColumn CellTemplate='{StaticResource nameTemplate}' Width='300' Header='Name'/>
                        <GridViewColumn CellTemplate='{StaticResource namespaceTemplate}' Width='300' Header='Namespace'/>
                    </GridView>
                </ListView.View>
                <x:Type TypeName='Visual'/>
                <x:Type TypeName='FrameworkElement'/>
                <x:Type TypeName='FrameworkContentElement'/>
            </ListView>
        </StackPanel>
    </Page>
    
    Permalink

    It’s a bit tricky because WPF doesn’t ‘realize’ the child nodes until they get rendered and you will also have to use some not very straight forward APIs to obtain the child. So, you will have to do something like this:

    
    // First set IsExpanded to true.   
    tviParent.IsExpanded = true;   
      
    // Then wait for the child items to get generated   
    if (tviParent.ItemContainerGenerator.Status != System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)   
        tviParent.ItemContainerGenerator.StatusChanged += new EventHandler(TempItemContainerGenerator_StatusChanged);   
    else  
        // If child items are already generated   
        this.OnReadyToSelect();   
      
      
      
      
    private void OnReadyToSelect()   
    {   
        // Here you can obtain and select any child of the currently selected TreeViewItem using it’s ItemContainerGenerator.    
        TreeViewItem childItem = tviParent.ItemContainerGenerator.ContainerFromItem(collectionItem); //Or specify an index.   
           
        childItem.IsSelected = true;   
    }  
    
    Permalink

    Sometimes you might have to specify a HierarchicalDataTemplate for a templated type. If so, you can only do this in code-behind. (If you have to do this in XAML try wrapping that template type within a non-templated dummy type.)

    For example, if you have to do something like this:

    
                <HierarchicalDataTemplate ItemsSource='{Binding}'  
                                          DataType='{x:Type local:MyTemplatedList<int>}'>   
                    <TextBlock Text='{Binding Name}'></TextBlock>  
                </HierarchicalDataTemplate>  
    

    The above wouldn’t compile because the XAML compiler doesn’t support this.

    So, you will have to do this in code-behind instead:

    
    using MyListType = MyTemplatedList;
    
    // Then in Window’s constructor for example:
    HierarchicalDataTemplate hdt = new HierarchicalDataTemplate(typeof(MyListType));   
    hdt.ItemsSource = new Binding();   
    FrameworkElementFactory tb = new FrameworkElementFactory(typeof(TextBlock));   
    tb.SetBinding(TextBlock.TextProperty, new Binding('Name'));   
    hdt.VisualTree = tb;   
    this.Resources[new DataTemplateKey(typeof(CountryList))] = hdt;  
    

    Note that the above code also illustrates how to add a HierarchicalDataTemplate resource to the Resources list without specifying a key.

    Permalink

    WPF lets you specify a negative value for the Border’s Margin. This way the available size for the children of the Border will not reduce when a Border is rendered.

    
    <Border Margin='-1,-1,-1,-1' BorderThickness='1' BorderBrush='Black'>
          <MyControls/> 
     </Border>
    
    Permalink

    Here is a sample XML and how it gets bound to a tree. The XML is of the form:

    CATEGORY
    ——REPORT
    —–CATEGORY
    ———-REPORT
    ——CATEGORY
    ———–CATEGORY
    —————–REPORT

    See how there can be any number of Category levels and the Reports can appear at any level too.

    Here is the sample code to bind this to the tree: (For better code formatting take a look at this incident in the MSDN Forums: A xml string…need to place nodes in a treeview.

    [XAML]
          <Window.Resources>  
            <XmlDataProvider x:Key='myReportsData' XPath='CATEGORY'  IsInitialLoadEnabled='True'>   
                <x:XData>  
                    <CATEGORY NAME='main 1' xmlns=''>   
                        <CATEGORY NAME='sub main 1'>   
                            <REPORT NAME='report111'>   
                            </REPORT>  
                        </CATEGORY>  
                        <CATEGORY NAME='test2222'>   
                            <CATEGORY NAME='test3333'>   
                                <REPORT NAME='report_test222'>   
                                </REPORT>  
                            </CATEGORY>  
                            <CATEGORY NAME='test555'>   
                                <REPORT NAME='report_test333'>   
                                </REPORT>  
                            </CATEGORY>  
                        </CATEGORY>  
                    </CATEGORY>  
                </x:XData>  
            </XmlDataProvider>  
            <HierarchicalDataTemplate DataType='CATEGORY'  ItemsSource ='{Binding XPath=*}'>   
                <TextBlock Text='{Binding XPath=@NAME}' />  
                </HierarchicalDataTemplate>  
            <DataTemplate DataType='REPORT'>   
                <TextBlock Text='{Binding XPath=@NAME}' />  
            </DataTemplate>  
        </Window.Resources>  
        <TreeView Name='myTreeView' Background='Aqua' >  
            <TreeView.ItemsSource>  
                <Binding Source='{StaticResource myReportsData}'/>   
            </TreeView.ItemsSource>  
        </TreeView>  
    
    
    Permalink

    For example, if you have to bind to a hierarchical data source containing data like this:

    Companies
        Company
           Departments
              Department
                 Employees
                    Employee
                 Computers
                    Computer
    

    Where the Department type has 2 lists – Employees and Computers as follows:

    
    namespace HierarchicalData.Classes
    {
        public class Department
        {
            public string Name { get; set; }
    
            List _employees = new List();
    
            public List Employees
            {
                ...
            }
            List _computers = new List();
    
            public List Computers
            {
                ...
            }
        }
    }
    

    Then you will have to create templates as follows:

    
            <local:CompanyList x:Key='companies'/>
    
            <HierarchicalDataTemplate x:Key='EmployeeTemplate'>
                <TextBlock Text='{Binding Path=Name}' />
            </HierarchicalDataTemplate>
    
            <HierarchicalDataTemplate x:Key='ComputerTemplate'>
                <TextBlock Text='{Binding Path=Name}' />
            </HierarchicalDataTemplate>
    
            <HierarchicalDataTemplate x:Key='DepartmentTemplate'>
                <TreeViewItem Header='{Binding Path=Name}'>
                    <TreeViewItem Header='Employees' ItemsSource='{Binding Path=Employees}'
                              ItemTemplate='{StaticResource EmployeeTemplate}'/> 
                    <TreeViewItem Header='Computers' ItemsSource='{Binding Path=Computers}'
                              ItemTemplate='{StaticResource ComputerTemplate}'/>                
                </TreeViewItem>
            </HierarchicalDataTemplate>
    
            <HierarchicalDataTemplate x:Key='CompanyTemplate'
                        ItemsSource='{Binding Path=Departments}' 
                        ItemTemplate='{StaticResource DepartmentTemplate}'> 
                <TextBlock Text='{Binding Path=Name}' />
            </HierarchicalDataTemplate>
    
            <TreeView Name='_myTreeView' Margin='0,0,0,0' 
              ItemsSource='{Binding Source={StaticResource companies}}' 
              ItemTemplate='{StaticResource CompanyTemplate}'/>
    
    Permalink

    ComboBox can be bound to an enum in XAML or in code. The below code shows binding to the ‘Visibility’ enum,

    [XAML]
    
    <ObjectDataProvider x:Key='VisibilityList' ObjectType='{x:Type sys:Enum}' MethodName='GetValues'>
    	<ObjectDataProvider.MethodParameters>
    		<x:TypeExtension TypeName='sys:Visibility'>
    	</ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
    
    <ComboBox x:Name='ComboBox1' ItemsSource='{Binding Source={StaticResource VisibilityList}}' SelectedIndex='0' />
    
    

    Same thing in code-behind:

    [C#]
    
    // Setup the binding as follows:
    comboBox1.ItemsSource = Enum.GetValues(typeof Visibility);
    
    

    You can retrieve the selected enum value at any time using a simple cast as follows:

    [C#]
    Visibility visibility = (Visibility)this.myCombo.SelectedItem;
    
    Permalink

    It’s possible that you have a list of commands that you simply want to bind to a context menu. You can do so as follows.

    For example, if you have list of custom commands, each of this type:

    [C#]
    public class MyCommand
    {
    public Name{get; set;}
    public Command{get; set;}
    }
    

    Then you can bind a list containing the above items to a ContextMenu as follows:

    
    <ContextMenu>
      <ContextMenu.ItemContainerStyle>
        <Style TargetType='{x:Type MenuItem}'>
          <Setter Property='Command' Value='{Binding ContextMenuItemCommand}'/>
        </Style>
      </ContextMenu.ItemContainerStyle>
    </ContextMenu>
    
    <ContextMenu ItemsSource={StaticResource myList}></ContextMenu>
    
    Permalink

    You can do this easily by extending the ApplicationCommands.Copy command as follows:

    See this forum for better formatting of the code ListView Copy to clipboard selected row.

    [XAML]
    <ListBox x:Name='myListBox' SelectionMode='Multiple'>   
        <ListBox.Items>  
            <ListBoxItem>Item1</ListBoxItem>  
            <ListBoxItem>Item2</ListBoxItem>  
            <ListBoxItem>Item3</ListBoxItem>  
            <ListBoxItem>Item4</ListBoxItem>  
        </ListBox.Items>  
    </ListBox>  
    

    In your code behind:

    [C#]
            public Window1()     
            {     
                this.InitializeComponent();   
      
                CommandBinding cb = new CommandBinding(ApplicationCommands.Copy, CopyCmdExecuted, CopyCmdCanExecute);   
      
                this.myListBox.CommandBindings.Add(cb);   
            }   
            void CopyCmdExecuted(object target, ExecutedRoutedEventArgs e)   
            {   
                ListBox lb = e.OriginalSource as ListBox;   
                string copyContent = String.Empty;   
                // The SelectedItems could be ListBoxItem instances or data bound objects depending on how you populate the ListBox.   
                foreach (ListBoxItem item in lb.SelectedItems)   
                {   
                    copyContent += item.Content.ToString();   
                    // Add a NewLine for carriage return   
                    copyContent += Environment.NewLine;   
                }   
                Clipboard.SetText(copyContent);   
            }   
            void CopyCmdCanExecute(object sender, CanExecuteRoutedEventArgs e)   
            {   
                ListBox lb = e.OriginalSource as ListBox;   
                // CanExecute only if there is one or more selected Item.   
                if (lb.SelectedItems.Count > 0)   
                    e.CanExecute = true;   
                else  
                    e.CanExecute = false;   
            }   
    
    Permalink

    You can bind B’s Width and Height to that of A’s. For example, in the XAML where you define B:

    [XAML]
    <local:B Width='{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type A}}, Path=Width}' /local:B>
    

    If there is an ActualWidth property in A, then you might want to bind B’s Width to that instead. Do the same for Height.

    Permalink

    You can do so as follows:

    [C#]
                this.myList.SelectedItem = o;
                // In case the item is out of view. If so, the next line could cause an exception without bringing this item to view.
                myList.ScrollIntoView(this.myList.SelectedItem);
                ListViewItem lvi = (ListViewItem)myList.ItemContainerGenerator.ContainerFromIndex(myList.SelectedIndex);
                lvi.Focus();
    
    Permalink

    One reason your binding to the SelectedValue may not work is if you have manually added ComboBoxItems as follows:

    [XAML]
    <ComboBox Name='mycombo' SelectedValue='{Binding Path=operator, Mode=TwoWay}' Width = '50'>   
    	<ComboBoxItem Content=''></ComboBoxItem>  
    	<ComboBoxItem>EQ</ComboBoxItem>  
    	<ComboBoxItem>NE</ComboBoxItem>  
    	<ComboBoxItem>CH</ComboBoxItem>  
    	<ComboBoxItem>GE</ComboBoxItem>  
    	<ComboBoxItem>LE</ComboBoxItem>  
    </ComboBox> 
    

    Instead, set the ItemsSource property to a list of strings as follows and the SelectedValue data binding will work fine:

    [XAML]
    <Window.Resources>  
            <src:MyList x:Name='myList' x:Key='myList'></src:MyList>  
        </Window.Resources>  
        
    <ComboBox Name='mycombo' SelectedValue='{Binding Path=Code, Mode=TwoWay}'    
                      ItemsSource='{StaticResource myList}' Width = '50' Height='30' >  
    

    Code Behind:

    [C#]
        public class MyList : List   
        {   
            public MyList()    
            {   
                this.Add('');   
                this.Add('EQ');   
                this.Add('NE');   
                this.Add('CH');   
                this.Add('GE');   
                this.Add('LE');   
            }   
      
        }
    
    Permalink

    With a listbox like this defined in your XAML:

    [XAML]
    <ListBox x:Name='myLB' ></ListBox>
    

    You can do so in your code-behind as follows:

    [C#]
            public MyWindow()
            {
                InitializeComponent();
    
                Binding binding = new Binding();
                binding.Source = this;
                PropertyPath path = new PropertyPath('ListSource');
                binding.Path = path;
                // Setup binding:
                BindingOperations.SetBinding(this.myLB, ListBox.ItemsSourceProperty, binding);
            }
    
            public string[] ListSource
            {
                get { return new string[] { 'testing', 'test1' };}
            }
    
    Permalink

    You can do so by listening to the ComponentDispatcher.ThreadPreprocessMessage in your window as follows:

    [C#]
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using swf = System.Windows.Forms;
    using System.Windows.Interop;
    using System.Windows.Forms.Integration;
    using System.Windows.Input;
    
    namespace WpfTestHarness
    {
        public partial class CustomShortcutHandlingDemo : Window
        {
            public CustomShortcutHandlingDemo()
            {
                InitializeComponent();
    
                // Registering against a stack event will cause memory leak, please unregister this event when you are done with it.
                ComponentDispatcher.ThreadPreprocessMessage += ComponentDispatcher_ThreadPreprocessMessage;
            }
    
            const int WM_KEYDOWN = 0x100;
            const int WM_SYSKEYDOWN = 0x0104;
            private void ComponentDispatcher_ThreadPreprocessMessage(ref MSG msg, ref bool handled)
            {
                if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN)
                {
                    // Examine if the Control and Enter keys are pressed, we also need to make sure that the
                    // currently keyborad focused element is TextBox instance itself.
                    swf.Keys keyData = ((swf.Keys)((int)((long)msg.wParam))) | swf.Control.ModifierKeys;
                    if (((keyData & swf.Keys.Control) == swf.Keys.Control) &&
                        ((keyData & swf.Keys.Enter) == swf.Keys.Enter) &&
                        Keyboard.FocusedElement == textBox)
                    {
                        MessageBox.Show('Ctrl+Enter is pressed');
                    }
                }
            }
        }
    }
    
    Permalink

    You can change the background of the grid layout when one of its children gets keyboard focus by setting the IsKeyboardFocusWithin property. This can be done with the following code snippet,

    [XAML]
    <Window.Resources>
            <Style x:Key = "GridTriggerStyle" TargetType = "Grid">
                <Style.Triggers>
                    <Trigger Property = "IsKeyboardFocusWithin" Value = "True">
                        <Setter Property = "Background" Value = "Green" />
                    </Trigger>
                    <Trigger Property = "IsKeyboardFocusWithin" Value = "False">
                        <Setter Property = "Background" Value = "AliceBlue" />
                    </Trigger>
                </Style.Triggers>
           </Style>
        </Window.Resources>
         
        <Grid Name="testGrid" Style="{StaticResource GridTriggerStyle}">
            <Button Height="30" Width="100" Content="SampleButton1"/>
        </Grid>
           
    Permalink

    This same logic can be used to access the ItemsPresenter of other ItemsControls like ListView, etc.

    [C#]
    public partial class RetrieveItemsPanelDemo : Window
    {
        public RetrieveItemsPanelDemo()
        {
            InitializeComponent();
            ListBox listBox = new ListBox() { ItemsSource = Enumerable.Range(0, 10) };
            this.Content = listBox;
            listBox.Loaded += delegate
            {
                VirtualizingStackPanel itemsPanel = listBox.GetVisualChild();
                if (itemsPanel != null && itemsPanel.IsItemsHost)
                {
                    itemsPanel.PreviewMouseLeftButtonDown += delegate { MessageBox.Show('WPF'); };
                }
            };
        }
    }
    
    public static T GetVisualChild(this Visual referenceVisual) where T : Visual
    {
        Visual child = null;
        for (Int32 i = 0; i < VisualTreeHelper.GetChildrenCount(referenceVisual); i++)
        {
            child = VisualTreeHelper.GetChild(referenceVisual, i) as Visual;
            if (child != null && (child.GetType() == typeof(T)))
            {
                break;
            }
            else if (child != null)
            {
                child = GetVisualChild(child);
                if (child != null && (child.GetType() == typeof(T)))
                {
                    break;
                }
            }
        }
        return child as T;
    }
    
    
    Permalink

    In WPF, you can set something to be run on application idle or system idle using the Dispatcher instance of the UI thread as follows:

    [C#]
    // First declare the delgate.
    public delegate void OneArgDelegate(int weather);
    
    // This is the method that will be called on system idle:
    public void UpdateWeather(int weather)
    {
    ...
    }
    
    // Schedule the above method for execution in the UI thread on system idle.
    tomorrowsWeather.Dispatcher.BeginInvoke(
        System.Windows.Threading.DispatcherPriority.SystemIdle,
        new OneArgDelegate(UpdateUserInterface), 
        weather);
    

    The other dispatcher priority options that are available are:

    
    SystemIdle,
    ApplicationIdle,
    ContextIdle,
    Background,
    Input,
    Loaded,
    Render,
    DataBind,
    Normal,
    Send
    
    Permalink

    The following utility class (provided in this thread: Accessing and Mondifying DataTemplate Element Runtime for CellTemplate should help you achieve this:

    [C#]
        public static class ListViewHelper 
        { 
            public static FrameworkElement GetElementFromCellTemplate(ListView listView, Int32 column, Int32 row, String name) 
            { 
                if (row >= listView.Items.Count || row < 0) 
                { 
                    throw new ArgumentOutOfRangeException('row'); 
                } 
                GridView gridView = listView.View as GridView; 
    
                if (gridView == null) { return null; } 
                
                if (column >= gridView.Columns.Count || column < 0) 
                { 
                    throw new ArgumentOutOfRangeException('column'); 
                } 
                
                ListViewItem item = listView.ItemContainerGenerator.ContainerFromItem(listView.Items[row]) as ListViewItem; 
                
                if (item != null) 
                { 
                    GridViewRowPresenter rowPresenter = GetFrameworkElementByName(item); 
                    
                    if (rowPresenter != null) 
                    { 
                        ContentPresenter templatedParent = VisualTreeHelper.GetChild(rowPresenter, column) as ContentPresenter; 
                        DataTemplate dataTemplate = gridView.Columns[column].CellTemplate; 
                        if (dataTemplate != null && templatedParent != null) 
                        { 
                            return dataTemplate.FindName(name, templatedParent) as FrameworkElement; 
                        } 
                    } 
                } 
                return null; 
            } 
            private static T GetFrameworkElementByName(FrameworkElement referenceElement) where T : FrameworkElement 
            { 
                FrameworkElement child = null; 
                
                for (Int32 i = 0; i < VisualTreeHelper.GetChildrenCount(referenceElement); i++) 
                { 
                    child = VisualTreeHelper.GetChild(referenceElement, i) as FrameworkElement; 
                    System.Diagnostics.Debug.WriteLine(child); 
                    if (child != null && child.GetType() == typeof(T)) 
                    { 
                        break; 
                    } 
                    else if (child != null) 
                    { 
                        child = GetFrameworkElementByName(child); 
                        if (child != null && child.GetType() == typeof(T)) 
                        { 
                            break; 
                        } 
                    } 
                } 
                return child as T; 
            } 
        }
    
    Permalink

    You can create a template programatically by populating the VisualTree of the template.

    [C#]
    			DataTemplate template = new DataTemplate();
    
    			template.VisualTree = new FrameworkElementFactory(typeof(Path));
    
    			template.VisualTree.SetBinding(Path.StrokeProperty, new Binding('Stroke'));
    			template.VisualTree.SetBinding(Path.StrokeThicknessProperty, new Binding('StrokeThickness'));
    			template.VisualTree.SetBinding(Path.FillProperty, new Binding('Interior'));
    			template.VisualTree.SetBinding(Path.DataProperty, new Binding('Geometry'));
    
    
    Permalink

    The fact that you have duplicate entries probably suggests that you are binding to the wrong data source. But, in any case, there are possibly valid scenarios where this is necessary. Here is a solution.

    One way is to group the list by name using CollectionViewSource and then bind the Groups to the ListBox. Here is some code:

    (for better code formatting, look at this thread: Distinct Value Filter For ListBox

    If you Contracts collection is like this:

    [C#]
    public class Contracts : List    
        {   
            public Contracts()   
            {   
                this.Add(new Contract() { ContractKey = '1', Name = 'John' });   
                this.Add(new Contract() { ContractKey = '2', Name = 'Bill' });   
                this.Add(new Contract() { ContractKey = '3', Name = 'Bill' });   
            }   
        }   
      
        public class Contract   
        {   
            public string ContractKey { get; set; }   
            public string Name { get; set; }   
        }   
    

    Then you can use the CollectionViewSource to bind to it and group the colelction by Name as follows:

    [XAML]
      
          
      
               
      
               
                  
                       
                  
              
      
          
      
          
             	   
              
          
      
    

    This will render the listbox the way you want – ignoring the duplicate names. You can then interpret the selected item as follows:

    [XAML]
    private void lb_SelectionChanged(object sender, SelectionChangedEventArgs e)   
            {   
                CollectionViewGroup groupSelected = ((CollectionViewGroup)e.AddedItems[0]);   
                string name = groupSelected.Name;   
                // These contain the items within the group   
                //groupSelected.Items;   
            }   
    
    Permalink

    You can do so by first making the 2 animations a child of a single storyboard as follows:

    
    <BeginStoryboard>
        <Storyboard x:Name='Animation'>
            <Storyboard x:Name='FadeInStoryboard'/>
            <Storyboard x:Name='FadeOutStoryboard'/>
        </Storyboard
    </BeginStoryboard>
    
    Permalink

    Here are some examples:

    Example 1:

    
    animation.Completed += delegate  
                  {   
                      // Start the other animation after the end of the previous animation.   
                      index++;   
                      if (lstDefinitions.Count > index)   
                          this.PerformAnimations(index, lstDefinitions);   
                  };   
    

    Example 2:

    
    label.MouseDown += (sender, e) =>
            {
                Console.WriteLine('MouseDown:{0}', e.OriginalSource);
    
                //Not clear why this is needed, but I guess this can effectively bypass
                // any attempt from the parent control to capture the mouse inside MouseDown handler.
                e.Handled = true;
            };
    
    
    Permalink

    Here is a solution:

    [XAML]
    <Page
    
        xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
    
        xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
    
        xmlns:sys='clr-namespace:System;assembly=mscorlib'>
    
      <Page.Resources>
    
        <XmlDataProvider x:Key='CharacterData'>
    
          <x:XData>
    
            <Data xmlns=''>
    
              <Character First='Bart' Last='Simpson' Gender='M'/>
    
              <Character First='Homer' Last='Simpson' Gender='M'/>
    
              <Character First='Lisa' Last='Simpson' Gender='F'/>
    
              <Character First='Maggie' Last='Simpson' Gender='F'/>
    
              <Character First='Marge' Last='Simpson' Gender='F'/>
    
            </Data>
    
          </x:XData>
    
        </XmlDataProvider>
    
        <DataTemplate x:Key='LVTSimpleText'>
    
          <Border Width='Auto' Height='Auto' BorderBrush='#FF000000' 
    
              BorderThickness='0,0,2,2'>
    
            <TextBox Width='Auto' Height='Auto' Text='{Binding Value}' 
    
                TextWrapping='Wrap'/>
    
          </Border>
    
        </DataTemplate>
    
      </Page.Resources>
    
      <ListView ItemsSource='{Binding Source={StaticResource CharacterData},
    
          XPath=Data/Character}'>
    
        <ListView.View>
    
          <GridView>
    
            <GridViewColumn Header='First Name'>
    
              <GridViewColumn.CellTemplate>
    
                <DataTemplate>
    
                  <ContentControl Content='{Binding XPath=@First}' 
    
                      ContentTemplate='{StaticResource LVTSimpleText}' />
    
                </DataTemplate>
    
              </GridViewColumn.CellTemplate>
    
            </GridViewColumn>
    
            <GridViewColumn Header='Last Name'>
    
              <GridViewColumn.CellTemplate>
    
                <DataTemplate>
    
                  <ContentControl Content='{Binding XPath=@Last}' 
    
                      ContentTemplate='{StaticResource LVTSimpleText}' />
    
                </DataTemplate>
    
              </GridViewColumn.CellTemplate>
    
            </GridViewColumn>
    
            <GridViewColumn Header='Gender'>
    
              <GridViewColumn.CellTemplate>
    
                <DataTemplate>
    
                  <ContentControl Content='{Binding XPath=@Gender}' 
    
                      ContentTemplate='{StaticResource LVTSimpleText}' />
    
                </DataTemplate>
    
              </GridViewColumn.CellTemplate>
    
            </GridViewColumn>
    
          </GridView>
    
        </ListView.View>
    
      </ListView>
    
    </Page>
    
    
    
    Permalink

    This is kind of how Firefox lets you search texts – as you type in the search box the matching text all get highligted automatically. You can use this solution for other templatized controls as well.

    (For better formatting, take a look at this thread: How to color particular cell of the grid view?)

    [XAML]
    <Window x:Class='SDKSample.Window1'  
        xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'  
        xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'  
        Loaded='OnLoad'  
        xmlns:ds='clr-namespace:SDKSample'>   
        
      <Window.Resources>  
            <ds:MyBGConverter x:Key='myBGConverter'></ds:MyBGConverter>  
                <ObjectDataProvider x:Key='EmployeeInfoDataSource'  
               ObjectType='{x:Type ds:myEmployees}'/>   
          <!--Repeat this for all columns where you want this to happen-->  
            <DataTemplate x:Key='myCellTemplateFN'>   
              <DockPanel>  
                <TextBlock Foreground='Green' HorizontalAlignment='Center'>   
                  <TextBlock.Text>  
                    <Binding Path='FirstName'/>   
                  </TextBlock.Text>  
                    <TextBlock.Background>  
                        <MultiBinding Converter='{StaticResource myBGConverter}'>   
                            <MultiBinding.Bindings>  
                                <Binding ElementName='searchTB' Path='Text' />  
                                <Binding RelativeSource='{RelativeSource Self}'></Binding>  
                            </MultiBinding.Bindings>  
                        </MultiBinding>  
                    </TextBlock.Background>  
                </TextBlock>  
              </DockPanel>  
            </DataTemplate>  
      
        </Window.Resources>  
      <Grid>  
        <Grid.RowDefinitions>  
          <RowDefinition Height='50'/>   
          <RowDefinition/>  
        </Grid.RowDefinitions>  
        <Grid.ColumnDefinitions>  
          <ColumnDefinition/>  
          <ColumnDefinition/>  
        </Grid.ColumnDefinitions>  
        <TextBlock Grid.Row='0' Grid.Column='0' FontSize='14'  
                   HorizontalAlignment='Center'>   
          ListView created with XAML   
        </TextBlock>  
        <StackPanel Grid.Row='1' Grid.Column='0' HorizontalAlignment='Center'>   
          <ListView ItemsSource='{Binding Source=   
                                 {StaticResource EmployeeInfoDataSource}}'   
                    >  
            <ListView.View>  
              <GridView AllowsColumnReorder='true'  
                        ColumnHeaderToolTip='Employee Information'>   
                <GridViewColumn CellTemplate='{StaticResource myCellTemplateFN}'  
                                Header='First Name' Width='100'/>   
                <GridViewColumn DisplayMemberBinding=   
                                    '{Binding Path=LastName}'    
                                Header='Last Name' Width='100'/>   
                <GridViewColumn DisplayMemberBinding=   
                                    '{Binding Path=EmployeeNumber}'    
                                Header='Employee No.' Width='100'/>   
              </GridView>  
            </ListView.View>  
          </ListView>  
                <StackPanel Orientation='Horizontal'>   
                    <TextBlock>Enter Search String Here:</TextBlock>  
                    <TextBox x:Name='searchTB' MinWidth='100' Width='150'></TextBox>  
                </StackPanel>  
            </StackPanel>  
      </Grid>  
      
    </Window>  
    
    

    And add this to your code-behind:

    [C#]
    public class MyBGConverter : IMultiValueConverter   
        {  
            #region IMultiValueConverter Members   
      
            public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)   
            {   
                TextBlock lvi = (TextBlock)values[1];   
                string filter = (string)values[0];   
                if (filter != String.Empty && lvi.Text.ToLower().Contains(filter.ToLower()))   
                {   
                    return Brushes.Aqua;   
                }   
                else  
                    return Brushes.White;   
            }   
      
            public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)   
            {   
                throw new NotImplementedException();   
            }  
     
            #endregion   
        }   
      
        public class EmployeeInfo   
        {   
            private string _firstName;   
            private string _lastName;   
            private string _employeeNumber;   
      
            public string FirstName   
            {   
                get {return _firstName;}   
                set {_firstName = value;}   
            }   
      
            public string LastName   
            {   
                get {return _lastName;}   
                set {_lastName = value;}   
            }   
      
            public string EmployeeNumber   
            {   
                get {return _employeeNumber;}   
                set {_employeeNumber = value;}   
            }   
      
            public EmployeeInfo(string firstname, string lastname, string empnumber)   
            {   
                _firstName = firstname;   
                _lastName = lastname;   
                _employeeNumber = empnumber;   
            }   
        }   
        public class myEmployees :   
                ObservableCollection   
        {   
            public myEmployees()   
            {   
                Add(new EmployeeInfo('Jesper', 'Aaberg', '12345'));   
                Add(new EmployeeInfo('Dominik', 'Paiha', '98765'));   
                Add(new EmployeeInfo('Yale', 'Li', '23875'));   
                Add(new EmployeeInfo('Muru', 'Subramani', '49392'));   
            }   
        }  
    
    Permalink

    Getting hold of an element in a ControlTemplate is very easy, as this article explains:

    How do I programmatically interact with template-generated elements? Part I

    Sample code:

    
    Grid gridInTemplate = (Grid)myButton1.Template.FindName('grid', myButton1);
    

    But, if want to get hold of an item in a DataTemplate (which gets applied for each item in the ItemsControl), then there is more code involved as explained here:

    How do I programmatically interact with template-generated elements? Part II

    Sample Code:

    
    // Note that the ListBox must have
    // IsSynchronizedWithCurrentItem set to True for this to work
    ListBoxItem myListBoxItem = (ListBoxItem)(myListBox.ItemContainerGenerator.ContainerFromItem(myListBox.Items.CurrentItem));
    ContentPresenter myContentPresenter = FindVisualChild(myListBoxItem);
    DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
    TextBlock myTextBlock = (TextBlock)myDataTemplate.FindName('textBlock', myContentPresenter);
    
    Permalink

    ControlTemplate can be created for a HeaderedItemsControl as follows.

    [XAML]
    
    <!--Define a control template for a HeaderedItemsControl-->
    <Style TargetType='HeaderedItemsControl'>
      <Setter Property='Template'>
        <Setter.Value>
          <ControlTemplate TargetType='{x:Type HeaderedItemsControl}'>
            <StackPanel>
              <Grid>
                <Rectangle Fill='{TemplateBinding Background}'/>
                <ContentPresenter ContentSource='Header'/>
              </Grid>
              <Grid>
                <Rectangle Stroke='{TemplateBinding BorderBrush}'/>
                <ItemsPresenter Margin='2,0,0,0'/>
              </Grid>
            </StackPanel>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
    
    ...
    
    <HeaderedItemsControl  xmlns:sys='clr-namespace:System;assembly=mscorlib'
                           Header='My colors'
                           Background='SteelBlue'
                           BorderBrush='DarkSlateBlue'>
      <sys:String>Red</sys:String>
      <sys:String>Yellow</sys:String>
      <sys:String>Blue</sys:String>
      <sys:String>Green</sys:String>
    </HeaderedItemsControl>
    
    Permalink

    Expression Blend supports custom controls to be added to a WPF application.

    To add a custom control to a WPF application the following steps have to be performed.

    1. Select Add Reference from Project Menu.

    2. Browse and select the dll that contains the definition of the custom control.

    3. Select Asset library from toolbox.

    4. Select custom controls tab and select the necessary control from the list.

    Permalink
    [C#]
    
    Stream mystream = new IsolatedStorageFileStream( storeFileName, FileMode.Create, isoStorage );
    if( null != mystream )
    {
    XmlTextWriter xmlwriter = new XmlTextWriter(mystream, Encoding.UTF8);
          this.WriteDateToWriter( xmlwriter );
          xmlwriter.Flush();
    stream.Close();
    }
    
    
    Permalink

    Here is an example :

    [C#]
     
    public class MyStateControl : ButtonBase
    {
      public MyStateControl() : base() { }
      public Boolean State
      {
        get { return (Boolean)this.GetValue(StateProperty); }
        set { this.SetValue(StateProperty, value); } 
      }
      public static readonly DependencyProperty StateProperty = DependencyProperty.Register(
        'State', typeof(Boolean), typeof(MyStateControl),new PropertyMetadata(false));
    }
    
    
    Permalink

    The typical reason for specifying a read-only dependency property is that these are the properties that is used to determine the state, but where the state is defined in a multitude of factors. A typical example for a read-only property is IsMouseHover

    This example shows how to ’register’ an attached property as read-only. You can use dependency properties on any ’DependencyObject’ types.

    [C#]
    
    public static readonly DependencyProperty IsBubbleSourceProperty = DependencyProperty.RegisterReadOnly(
      'IsBubbleSource',
      typeof(Boolean),
      typeof(AquariumObject),
      new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender)
    );
    
    
    Permalink

    You can enumerate all the descendants of a visual object as follows :

    [C#]
    
    // Enumerate all the descendants of the visual object.
    static public void EnumVisual(Visual myVisual)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(myVisual); i++)
        {
            // Retrieve child visual at specified index value.
            Visual childVisual = (Visual)VisualTreeHelper.GetChild(myVisual, i);
    
            // Do processing of the child visual object.
    
            // Enumerate children of the child visual object.
            EnumVisual(childVisual);
        }
    }
    
    
    Permalink

    Note that in WPF all animations (element.BeginAnimation method) are executed asynchronously. So, if you call a bunch of BeginAnimation methods one after another in a for loop, they all will overlap and not really execute one after another.

    There is really no way to chain animations in WPF. You will have to basically listen to an animation’s Completed event and then trigger the next animation. To make such code efficient and scalable I came up with this recursion with in-line event handler based approach:

    Let us say you want to increase the width of these 2 rectangles one after the other via animation:

    [XAML]
    <Canvas>  
            <Rectangle x:Name='rect1' Canvas.Top='0' Width='30' Height='30' Fill='Aqua'></Rectangle>  
            <Rectangle x:Name='rect2' Canvas.Top='50' Width='30' Height='30'  Fill='Azure'></Rectangle>  
    </Canvas>  
    

    The code-behind for this would be:

    [C#]
    private void Window_Loaded(object sender, RoutedEventArgs e)   
            {   
      
                DoubleAnimation da = new DoubleAnimation(100, new Duration(TimeSpan.FromSeconds(3)));   
                List list = new List();   
                list.Add(new object[] { rect1, Rectangle.WidthProperty, da});   
                list.Add(new object[] { rect2, Rectangle.WidthProperty, da });   
      
                this.PerformAnimations(0, list);   
            }   
      
            private void PerformAnimations(int index, List lstDefinitions)   
            {   
                object[] definition = lstDefinitions[index] as object[];   
                AnimationTimeline animation = definition[2] as AnimationTimeline;   
                  animation.Completed += delegate  
                  {   
                      // Start the other animation after the end of the previous animation.   
                      index++;   
                      if (lstDefinitions.Count > index)   
                          this.PerformAnimations(index, lstDefinitions);   
                  };   
                  ((UIElement)definition[0]).BeginAnimation((DependencyProperty)definition[1], (AnimationTimeline)definition[2]);   
            }
    

    The idea is to maintain a list of ‘animation definitiions’ and execute animations from this list recursively.

    Permalink

    Instead of setting up event handlers on all the MenuItems you can listen to those events as they bubble up to the context menu as follows:

    [XAML]
    
                MenuItem1
                MenuItem2
                MenuItem3
                MenuItem4
    
    

    Or you can setup the same thing in code as follows:

    [C#]
    menuItem1.AddHandler(MenuItem.Click, new RoutedEventHandler(MnItem_Click));
    

    The event handler would then be something like:

    
    private void MnItem_Click(object sender, RoutedEventArgs e)
    {
    	MenuItem item = e.Source as MenuItem;
                
    	....
    }
    
    Permalink

    Instead of setting up event handlers on all the tree nodes you can listen to those events as they bubble up to the tree as follows:

    [XAML]

    <TreeView TreeViewItem.Selected="TvItem_Selected">
    <TreeViewItem>Node1</TreeViewItem>
    <TreeViewItem>Node2</TreeViewItem>
    <TreeViewItem>Node3</TreeViewItem>
    <TreeViewItem>Node4</TreeViewItem>
    </TreeView>

    Or you can setup the same thing in code as follows:

    [C#]
    treeView1.AddHandler(TreeViewItem.SelectedEvent, new RoutedEventHandler(TvItem_Selected));
    

    The event handler would then be something like:

    private void TvItem_Selected(object sender, RoutedEventArgs e)
    {
    	TreeViewItem item = e.Source as TreeViewItem;
                
    	....
    }
    

    Permalink

    You can change the colors in your ListBox’s resources, as follows:

    [XAML]
    <ListBox>
                <ListBox.Resources>
                    <SolidColorBrush x:Key='{x:Static SystemColors.HighlightBrushKey}' Color='White'/>
                    <SolidColorBrush x:Key='{x:Static SystemColors.HighlightTextBrushKey}' Color='Black'/>
                    <SolidColorBrush x:Key='{x:Static SystemColors.ControlBrushKey}' Color='White'/> 
                </ListBox.Resources>
    </ListBox>
    

    The 3rd color above is the gray color in which the selected item background is rendered when the listbox does not have the focus.

    Permalink

    To specify custom sorting using a custom implementation of an IComparer, you will have to use a CollectionViewSource, get it’s default view and set it’s CustomSort property as follows:

    Sample ListBox bound to a CollectionViewSource:

    
    <Window x:Class='WindowsApplication1.Window1'
        xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
        xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
        xmlns:scm='clr-namespace:System.ComponentModel;assembly=windowsbase'
    >
      <Window.Resources>
        <XmlDataProvider x:Key='list' >
          <x:XData>
            <Items xmlns=''>
              <Item>
                <Name>David</Name>
                <Age>20</Age>
              </Item>
              <Item>
                <Name>Marcus</Name>
                <Age>25</Age>
              </Item>
              <Item>
                <Name>George</Name>
                <Age>25</Age>
              </Item>
              <Item>
                <Name><![CDATA[Peter&#M]]></Name>
                <Age>25</Age>
              </Item>
            </Items>
          </x:XData>
        </XmlDataProvider>
        <CollectionViewSource
            Source='{Binding Source={StaticResource list}, XPath=Items/Item/Name}'
            x:Key='data'/>
      </Window.Resources>
      <ListBox
          Name='lb1'
          DisplayMemberPath='Name'
          ItemsSource='{Binding Source={StaticResource data}}'/>
    </Window>
    

    Then in code-behind specify the custom comparer as follows:

    
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            this.lb1.Loaded += delegate
            {
                CollectionViewSource cvs = this.TryFindResource('data') as CollectionViewSource;
                if (cvs != null)
                {
                    ListCollectionView view = cvs.View as ListCollectionView;
                    if (view != null)
                    {
                        view.CustomSort = new XmlComparer();
                    }
                }
            };
        }
    
        public class XmlComparer : IComparer
        {
            public Int32 Compare(Object x, Object y)
            {
                XmlElement a = x as XmlElement;
                XmlElement b = y as XmlElement;
                if (a != null && b != null)
                {
                    return String.Compare(a.InnerText, b.InnerText);
                }
    
                return -1;
            }
        }
    }
    
    Permalink

    WPF doesn’t provide a MouseHover event and instead provides a much more flexible and high-level Tooltip support. To simulate MouseHover, you will first set the tooltip for the element in question to some dummy text and then listen to the TooltipOpening event where you would mark it as ‘Handled’ as follows:

     [XAML]
    <Canvas ToolTipOpening='Canvas_ToolTipOpening' ToolTipService.ToolTip='Testing'>
    </Canvas>
    
     [C#]
            private void Canvas_ToolTipOpening(object sender, ToolTipEventArgs e)
            {
                e.Handled = true;
                // More code goes here:
            }
    
    Permalink

    Let us say you have your application running in a folder called C:\MyApp. Then if you want to load a FlowDocumentContent.xaml from a folder called C:\Contentthen this is easily done by first defining a FlowDocumentReader in your app like so:

     [XAML]
                  <FlowDocumentReader Name='myFlowDocument' ViewingMode='Scroll'  IsTwoPageViewEnabled='False' IsPageViewEnabled='False'>
                  </FlowDocumentReader>
    

    And load the xaml file as follows:

     [C#]
                	FileStream xamlFile = new FileStream(filePath, FileMode.Open, FileAccess.Read);
    	// This will work, only if the top-level element in the document is FlowDocument
                	FlowDocument content = XamlReader.Load(xamlFile) as FlowDocument;
    
    	this.myFlowDocument.Document = content;
    
                	xamlFile.Close();
    

    But if you have references to sub-folders in your document. For example, if you are referring to images under this folder C:\Content\Images, then those images wouldn’t be found by the parser because the parser is executing with the application directory context whereas the document contents are in a different directory. To make this work, you can force a context on the parser as follows:

     [C#]
                	ParserContext context = new ParserContext();
                	context.BaseUri = new Uri(filePath, UriKind.Absolute);
                	FlowDocument content = XamlReader.Load(xamlFile, context) as FlowDocument;
    
    Permalink

    By default when you bind the ListBox’s ItemsSource to a collection of objects of a custom type, the ListBox would simply call the object’s ToString() method to determine what to display for each item. The ToString method would normally simply display the type name of the object.

    If you instead want a value of a property of the object to be displayed in the listbox, you should set the DisplayMemberPath property of the ListBox to that property name as follows:

    
    <ListBox ItemsSource='{StaticResource myCollection}' DisplayMemberPath='FirstName' />
    
    Permalink

    Let us say you want have a hierarchical list like this:

    
    - Group
    |
    |--- Products
    |   |--- Product1
    |   |--- Product2
    |--- Service
    |   |--- Service1
    |   |--- Service2
    

    And the underlying Group type defined like this:

    
    public class Group
    {
    
    public string Name{...}
    
    public ProductCollection Products{...}
    
    public ServiceCollection Services{...}
    
    }
    

    Then you will have trouble binding this to a TreeView to get the above indicated effect. To achieve the above effect, you should first implement a dummy ‘Children’ collection that is a combination of the Products and Services collection as follows:

    
    public class Group
    {
    
    public string Name{...}
    
    public ProductCollection Products{...}
    
    public ServiceCollection Services{...}
    
    public IList Children{/*Combine Products and Services and return the list here. This could be just a read-only list.*/}
    
    }
    

    Then create a HierarchicalDataTemplate for the Group object as follows:

    [XAML]
    <HierarchicalDataTemplate DataType='{x:Type src:Group}' ItemsSource='{Binding Path=Children}'>   
      
    <TextBlock Text='{Binding Path=Name}'/>   
      
    </HierarchicalDataTemplate>  
    
    

    This will render both the Products and Services list as siblings at the same level.

    You should also declare HierarchicalDataTemplates for the Product and Service types you might have defined.

    You would of course, bind the tree to a collection of Group items.

    Permalink

    The TabItems have a Visibility property which can be set to Collapsed (no space will be reserved for this tab) or Hidden (not rendered, but space will be reserved for this tab).

    
    [XAML]
     
            <TabControl x:Name='tabControl1'>
                <TabItem Header='Tab1'></TabItem>
                <TabItem Header='Tab2' Visibility='Hidden'></TabItem>
                <TabItem Header='Tab3' Visibility='Collapsed'></TabItem>
                <TabItem Header='Tab4'></TabItem>
            </TabControl>  
    
    Permalink

    You can set a ‘ToolTipService’ property that causes a brief delay before a ToolTip displays. You set the properties of the ‘ToolTipService’ class by attaching them directly to the element that exposes the tooltip.

    [XAML]
     
    <TextBox HorizontalAlignment='Left' ToolTipService.InitialShowDelay='1500'
    ToolTip='Useful information goes here.'>
         ToolTip with delay
       </TextBox>
    
    
    Permalink

    This is very easy to do in XAML, as follows:

    [XAML]
            <TextBlock x:Name='myTextBlock' Width='100' Height='40'>
                <Button>Test</Button>
            </TextBlock>
    

    And you can do something similar in C# as follows:

    [C#]
                Button btn = new Button();
                btn.Content = 'Test';
                this.myTextBlock.Inlines.Add(btn);
    
    Permalink

    Let us say you have a hierarchical list like this:

    
    - Division1
    |
    |--- Department1
    |   |--- Room1
    |   |--- Room2
    |--- Department2
    |   |--- Room3
    |   |--- Room4
    - Division2
    (......) 
    

    With corresponding types like this:

    [C#]
    public class Division
    {
    
    public string Name{...}
    
    public DepartmentsCollection Departments{...}
    
    }
    
    public class Department
    {
    
    public string Name{...}
    
    public RoomsCollection Rooms{...}
    
    }
    
    public class Room
    {
    public string Name{....}
    }
    
    

    You could then bind a collection of Divisions to a tree to achieve the above look and feel by defining a HierarchicalDataTemplate for Division and Department and a DataTemplate for Room types, as follows:

    [XAML]
    <HierarchicalDataTemplate DataType='{x:Type src:Division}' ItemsSource='{Binding Path=Departments}'>   
      
    <TextBlock Text='{Binding Path=Name}'/>   
      
    </HierarchicalDataTemplate>  
    
    <HierarchicalDataTemplate DataType='{x:Type src:Department}' ItemsSource='{Binding Path=Rooms}'>   
      
    <TextBlock Text='{Binding Path=Name}'/>   
      
    </HierarchicalDataTemplate>  
    
    <DataTemplate DataType='{x:Type src:Room}'>   
      
    <TextBlock Text='{Binding Path=Name}'/>   
      
    </DataTemplate>  
    
    

    You can then bind the TreeView to a collection of Divisions.

    [XAML]
    <!--myDivisonsCollection could be an ObjectDataSource returning the list of Divisions collection --!>
    <TreeView ItemsSource='{Binding Source={StaticResource myDivisionsCollection}}'></TreeView>
    
    Permalink

    The ComboBox, like the other ItemsControl can be bound to any IList, ObservableCollection or ObjectDataProvider (containing a list type data) as explained in this MSDN topic:

    ItemsControl Content Model Overview

    If bound to an ObservableCollection, changes happening in the collection will automatically reflect in the ComboBox.

    You can also bind to XML Data using an XMLDataProvider as explained in this topic:

    How to: Bind to XML Data Using an XMLDataProvider and XPath Queries

    Bind the ComboBox to a CollectionViewSource to be able to bind to sorted or grouped views of your list.

    CollectionViewSource Class

    You can also bind to a DataTable in an ADO.NET DataSet as follows:

    How to: Bind to an ADO.NET Data Source

    Permalink

    The ListBox, like the other ItemsControl can be bound to any IList, ObservableCollection or ObjectDataProvider (containing a list type data) as explained in this MSDN topic:

    ItemsControl Content Model Overview

    If bound to an ObservableCollection, changes happening in the collection will automatically reflect in the ListBox.

    You can also bind to XML Data using an XMLDataProvider as explained in this topic:

    How to: Bind to XML Data Using an XMLDataProvider and XPath Queries

    Bind the ListBox to a CollectionViewSource to be able to bind to sorted or grouped views of your list.

    CollectionViewSource Class

    You can also bind to a DataTable in an ADO.NET DataSet as follows:

    How to: Bind to an ADO.NET Data Source

    Permalink

    You can load a xaml file dynamically as follows:

    [C#]
    // This file should then be next to the exe. If not specify a relative path.
    FileStream xamlFile = new FileStream('ChartWindow.xaml', FileMode.Open, FileAccess.Read);
    
    Window win = XamlReader.Load(xamlFile) as Window;
    
    win.Show();
    

    Note that any code-behind associated with the above xaml will not be loaded/processed.

    In case, you have an assembly reference to a custom dll in the above xaml file, you should reference that assembly with a fully qualified namespace as follows:

    [XAML]
    xmlns:syncfusion='clr-namespace:Syncfusion.Windows.Chart;assembly=Syncfusion.Chart.WPF,Version=6.303.0.6,Culture=neutral,PublicKeyToken=3d67ed1f87d44c89'
    

    The above assembly should then be present in the GAC for the runtime to find it.

    Permalink

    You can choose to keep your Windows Forms application primarily intact and migrate portions of your application to WPF where it makes sense. You can do this by identifying those areas of your application that are a good fit for WPF features and convert only those areas to WPF. For example, you may want to convert only a few of your forms to WPF and keep the rest of the application based on Windows Forms. Using this method, you could simply popup instances of WPF pages or windows from your Windows Forms application. Additionally, you may want to actually swap-out Windows Forms controls for WPF controls on a form resulting in a hybrid form when the controls co-exist in peaceful harmony.

    Permalink

    This outlines the basic procedure to host WPF content in a Win32 window. The key to hosting WPF content on a Win32 window is the ‘HwndSource’ class. This class wraps the WPF content in a Win32 window, allowing it to be incorporated into your user interface (UI) as a child window. The following approach combines the Win32 and WPF in a single application.
    A. Implement your WPF content as a managed class.
    B. Implement a Win32 application with C++ / CLI. If you are starting with an existing application and unmanaged C++ code, you can usually enable it to call managed code by changing your project settings to include the /clr compiler flag.
    C. Set the threading model to single-threaded apartment (STA).
    D. Handle the WM_CREATE notification in your window procedure and do the following :
    1.Create a new HwndSource object with the parent window as it’s parent parameter.
    2.Create an instance of your WPF content class.
    3.Assign a reference to the WPF content object to the RootVisual property of the HwndSource.
    4.Get the HWND for the content. The Handle property of the HwndSource object contains the windowhandle (HWND). To get an HWND that you can use in the unmanaged part of your application, cast Handle.ToPointer() to an HWND.
    E. Implement a managed class that contains a static field to hold a reference to your WPF content. This class allows you to get a reference to the WPF content from your Win32 code.
    F. Assign the WPF content to the static field.
    G. Receive notifications from the WPF content by attaching a handler to one or more of the WPF events.
    H. Communicate with the WPF content by using the reference that is stored in the static field to set the properties and so on.

    Note:
    You can also use Extensible Application Markup Language (XAML) to implement your WPF content. However, you will have to compile it separately as a dynamic-link library (DLL) and reference that DLL from your Win32 application. The remainder of the procedure is similar to that outlined above.

    Permalink

    You can choose to keep your Windows Forms application primarily intact and migrate portions of your application to WPF where it makes sense. You can do this by identifying those areas of your application that are a good fit for WPF features and convert only those areas to WPF. For example, you may want to convert only a few of your forms to WPF and keep the rest of the application based on Windows Forms. Using this method, you could simply popup instances of WPF pages or windows from your Windows Forms application. Additionally, you may want to actually swap-out Windows Forms controls for WPF controls on a form resulting in a hybrid form when the controls co-exist in peaceful harmony.

    Permalink

    You can have a WPF application popup a Windows Form much in the same way that you can popup a WPF window from a Windows Forms application. Furthermore, you can place Windows Forms controls side-by-side with WPF controls on a WPF window or page-by-page using the WindowsFormsHost control that ships as part of the interoperability layer.

    Permalink

    Separator controls inside Menu elements appear differently from Separator controls outside a Menu. When you create a Menu with a Separator, the control automatically applies the Style identified by the SeparatorStyleKey property. Styles are placed in resource dictionaries and are searched for by their keys. To change the Style of a Separator inside a Menu, you must use the SeparatorStyleKey property to create your new Style.

    The following example demonstrates this.

    [XAML]
    
    <Style x:Key='{x:Static MenuItem.SeparatorStyleKey}' TargetType='Separator'>
      <Setter Property='OverridesDefaultStyle' Value='true' />
      <Setter Property='Template'>
        <Setter.Value>
          <ControlTemplate TargetType='{x:Type Separator}'>
            <Border Width='30' Height='4' Margin='4' Background='Red'/>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
    
    
    Permalink

    The ‘BitmapMetaData’ class provides metadata information contained by the image. This metadata can be one metadata schema or a combination of different schemes.

    WPF inherently supports the following image schemas:

  • ExchangableImageFile (Exif).
  • PNG Textual Data.
  • ImageFileDirectory (IFD).
  • InternationalPressTelecommunicationsCouncil (IPTC).
  • ExtensibleMarkupLanguage (XMP).
  • [C#]
    
                Stream pngStream = new System.IO.FileStream('winter.png', FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
                PngBitmapDecoder pngDecoder = new PngBitmapDecoder(pngStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
                BitmapFrame pngFrame = pngDecoder.Frames[0];
                InPlaceBitmapMetadataWriter pngInplace = pngFrame.CreateInPlaceBitmapMetadataWriter();
                if (pngInplace.TrySave() == true)
                { 
    	pngInplace.SetQuery('/Text/Author', 'Me'); 
                }
                pngStream.Close();
    
    
    Permalink

    Use the TransformedBitmap element to rotate an image.

    [XAML]
    
    <Image Width='200' Height='200'>
    	<Image.Source>
    		<TransformedBitmap Source='C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\Winter.jpg'>
    			<TransformedBitmap.Transform>
    				<RotateTransform Angle='270' />
    			</TransformedBitmap.Transform>
    		</TransformedBitmap>
    	</Image.Source>
    </Image> 
    
    
    Permalink

    This can be done by using the ‘FormatConvertedBitmap’ class. The image is converted to the spcified PixedFormat type.

    The following code snippet shows the conversion of an image to grayscale.

    [XAML]
    <Image Width='200' Height='200' >
    	<Image.Source>
    		<FormatConvertedBitmap Source='C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\Winter.jpg' DestinationFormat='Gray4' />
    	</Image.Source>
    </Image>
    
    
    Permalink

    This example shows how to reflect the ‘Zoom’ value of a DocumentViewer in a TextBlock.

    [XAML]
    
    <Window x:Class='SDKSample.Window1'
            xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
            xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height='*' />
          <RowDefinition Height='*' />
        </Grid.RowDefinitions>
    
        <DocumentViewer Name='dvZoomSource' Grid.Row='0' />
    
        <TextBlock  Grid.Row='1'
            Text='{Binding ElementName=dvZoomSource, Path=Zoom, Mode=OneWay}' />
      </Grid>
    </Window>
    
    
    Permalink

    The following style uses the ‘BasedOn’ attribute to extend the default DocumentViewer style.

    [XAML]
    
    <Window x:Class='SDKSample.Window1'
            xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
            xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
      <Window.Resources>
        <Style 
          x:Key='MyDVStyleExtend'
          BasedOn='{StaticResource {x:Type DocumentViewer}}' 
          TargetType='{x:Type DocumentViewer}'>
          <Setter Property='Background'>
            <Setter.Value>
              <LinearGradientBrush StartPoint='0.5,0' EndPoint='0.5,1'>
                <GradientStop Offset='0.0' Color='#CC99CCFF' />
                <GradientStop Offset='1.0' Color='White' />
              </LinearGradientBrush>
            </Setter.Value>
          </Setter>
        </Style>
      </Window.Resources>
      <Grid>
        <DocumentViewer  Style='{StaticResource MyDVStyleExtend}' Name='MyDocumentViewer'/>
      </Grid>
    </Window>
    
    
    Permalink

    This example uses the ContextMenuService.ShowOnDisabled property to show the context menu for a disabled button.

    [XAML]
    
    <Button Height='30' Content='Disabled Button' IsEnabled='False' 
         ContextMenuService.ShowOnDisabled='True'>
      <Button.ContextMenu>
        <ContextMenu>
          <MenuItem Header='Item 1'/>
          <MenuItem Header='Item 2'/>
          <MenuItem Header='Item 3'/>
        </ContextMenu>
      </Button.ContextMenu>
    </Button>
    
    
    Permalink

    Here is a custom style that changes the look and feel of the tabs (TabItems) in the corresponding window.

    [XAML]
    
    <Style TargetType='TabItem'>
      <Setter Property='BorderThickness' Value='3'/>
      <Setter Property='BorderBrush' Value='Red'/>
      <Setter Property='Background' Value='LightBlue'/>
      <Setter Property='VerticalContentAlignment' Value='Center'/>
      <Setter Property='HorizontalContentAlignment' Value='Center'/>
      <Setter Property='Template'>
        <Setter.Value>
          <ControlTemplate TargetType='{x:Type TabItem}'>
            <Border>
              <Grid>
                <Grid>
                  <Border CornerRadius='3,3,0,0' Background='{TemplateBinding Background}' 
                       BorderBrush='{TemplateBinding BorderBrush}' 
                       BorderThickness='{TemplateBinding BorderThickness}'/>
                </Grid>
                <Border BorderThickness='{TemplateBinding BorderThickness}' 
                     Padding='{TemplateBinding Padding}'>
                  <ContentPresenter ContentSource='Header' 
                     HorizontalAlignment='{TemplateBinding HorizontalContentAlignment}' 
                     VerticalAlignment='{TemplateBinding VerticalContentAlignment}'/>
                </Border>
              </Grid>
            </Border>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
    
    

    This is how the tabs look with the above style applied on them:

    Permalink

    Share with

    Share on twitter
    Share on facebook
    Share on linkedin

    Couldn't find the FAQs you're looking for?

    Please submit your question and answer.