MSDN documentation
http://msdn2.microsoft.com/en-us/library/ms754130.aspx
WPF Samples in MSDN:
ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETFX30SDK4VS.1033/wpf_samples/html/b7781121-4c27-4814-a8d8-e6e0be247c00.htm
WPF Sample files part of Windows SDK:
C:\Program Files\Microsoft SDKs\Windows\v6.0\Samples\WPFSamples.zip
Location of WPF samples:
http://blogs.msdn.com/wpfsdk/attachment/1495353.ashx
Using Templates to Customize WPF Controls
http://msdn.microsoft.com/msdnmag/issues/07/01/Foundations/
In here, you can also find DumpControlTemplate code from Chapter 25 that allows you to dump out a control's default template property.
Custom TreeView Layout in WPF
http://www.codeproject.com/useritems/CustomTreeViewLayout.asp
Advanced Custom TreeView Layout in WPF
http://www.codeproject.com/WPF/AdvancedCustomTreeViewLyt.asp
Dependency property syntax:
// dependency property for minimum number of pies
public int MinNumPies
{
get { return (int)GetValue(MinNumPiesProperty); }
set { SetValue(MinNumPiesProperty, value); }
}
public static readonly DependencyProperty MinNumPiesProperty =
DependencyProperty.Register("MinNumPies", typeof(int), typeof(RadialPanel));
Routed events syntax:
MSDN documentation
ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETFX30SDK4VS.1033/wpf_conceptual/html/1a2189ae-13b4-45b0-b12c-8de2e49c29d2.htm
// routed event
public static readonly RoutedEvent EventNameEvent = EventManager.RegisterRoutedEvent("EventName",
RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyEnclosingClass));
// A .NET event wrapper (optional)
public event RoutedEventHandler EventName
{
add { AddHandler(EventNameEvent, value); }
remove { RemoveHandler(EventNameEvent, value); }
}
{
...
RaiseEvent(new RoutedEventArgs(EventNameEvent, this));
...
}
Binding syntax:
FAQ on Binding from MSDN blog:
http://blogs.msdn.com/wpfsdk/archive/2006/10/19/wpf-basic-data-binding-faq.aspx
NOTE: Can’t seem to nest bindings, e.g. {Binding Source={Binding Source={StaticResource resourceName}}}
NOTE: Target property (i.e. the left-hand side of {Binding...} must be a dependency property.
NOTE: When the source property is not a dependency property, the target property won’t be updated as the source property changes. To get them to be synchronized, the source object needs to either 1) implement the System.ComponentModel.INotifyPropertyChanged interface which has the single PropertyChanged event, or 2) implement an XXXChanged event, where XXX is the name of the property whose value changed. (first approach is recommended)
// ElementName used to refer to a XAML element defined by x:Name and source property on that object accessed through property1.property2
{Binding ElementName=elementName, Path=property1.property2}
{Binding property1.property2, ElementName=elementName}
// ElementName used to refer to a XAML element defined by x:Name
{Binding ElementName=elementName}
// Source used to refer to data source defined in ResourceDictionary and source property on that object accessed through property1.property2
{Binding Source={StaticResource resourceName}, Path=property1.property2}
// Source used to refer to data source defined in ResourceDictionary
{Binding Source={StaticResource resourceName}}
// when used within a FrameworkElement/FrameworkContentElement that have the DataContext property set to some data source, all nested Binding references implicitly assume a Source property value equal to that DataContext
<StackPanel DataContext={StaticResource resourceName}>
<Label Content={Binding Path=property}/>
<ListBox ItemsSource={Binding}/>
</StackPanel>
// when used within a DataTemplate, the DataContext is automatically set to the appropriate Source object, i.e. for ItemTemplate, it’s the current item
<ListBox>
<ListBox.ItemTemplate>
<Image Source=“{Binding Path=property}”/>
</ListBox.ItemTemplate>
</ListBox>
Binding’s RelativeSource property syntax:
RelativeSource property of Binding can be used to refer to data source relative to the target element
// source element equals target element
<Binding RelativeSource={RelativeSource Self}>
// source element equals target element’s TemplatedParent, which is essentially the target element of the template
<Binding RelativeSource={RelativeSource TemplatedParent}>
// source element equals the closest parent of a given type
<Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type desiredType}}>
// source element equals the nth closest parent of a given type
<Binding RelativeSource={RelativeSource FindAncestor, AncestorLevel=n, AncestorType={x:Type desiredType}}>
// source element equals the previous data item in a data-bound collection
<Binding RelativeSource={RelativeSource PreviousData}}>
TemplateBinding syntax:
Data source for TemplateBinding is always the target element, and the path is any of its dependency properties.
TemplateBinding can’t be used outside of a template’s VisualTree property, so can’t use in a trigger. Instead, you can use {Binding RelativeSource={RelativeSource TemplatedParent}}
<ControlTemplate TargetType=“{x:Type Button}”>
<!-- following bindings are all the same -->
<TextBlock Text=“{TemplateBinding Property=Button.Content}”/>
<TextBlock Text=“{TemplateBinding Button.Content}”/>
<TextBlock Text=“{TemplateBinding Content}”/>
</ControlTemplate>
ValueConverter syntax:
<Application.Resources>
<local:SingleConverter x:Key=“converter1”/>
<local:MultiConverter x:Key=“converter2”/>
</Application.Resources>
// single binding
<Label Background=“{Binding Source={StaticResource source}, Path=property, Converter={StaticResource converter1}, ConverterParameter=parameter}”/>
public class SingleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
...
}
}
// multibinding
<ProgressBar ...>
<ProgressBar.Value>
<MultiBinding Converter=“{StaticResource converter2}, ConverterParameter=parameter”>
<Binding ...}”/>
<Binding ...}”/>
<Binding ...}”/>
</MultiBinding>
</ProgressBar.Value>
</ProgressBar>
public class MultiConverter : IMultiConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
object value1 = values[0];
object value2 = values[1];
...
}
}
http://msdn2.microsoft.com/en-us/library/ms754130.aspx
WPF Samples in MSDN:
ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETFX30SDK4VS.1033/wpf_samples/html/b7781121-4c27-4814-a8d8-e6e0be247c00.htm
WPF Sample files part of Windows SDK:
C:\Program Files\Microsoft SDKs\Windows\v6.0\Samples\WPFSamples.zip
Location of WPF samples:
http://blogs.msdn.com/wpfsdk/attachment/1495353.ashx
Using Templates to Customize WPF Controls
http://msdn.microsoft.com/msdnmag/issues/07/01/Foundations/
In here, you can also find DumpControlTemplate code from Chapter 25 that allows you to dump out a control's default template property.
Custom TreeView Layout in WPF
http://www.codeproject.com/useritems/CustomTreeViewLayout.asp
Advanced Custom TreeView Layout in WPF
http://www.codeproject.com/WPF/AdvancedCustomTreeViewLyt.asp
Dependency property syntax:
// dependency property for minimum number of pies
public int MinNumPies
{
get { return (int)GetValue(MinNumPiesProperty); }
set { SetValue(MinNumPiesProperty, value); }
}
public static readonly DependencyProperty MinNumPiesProperty =
DependencyProperty.Register("MinNumPies", typeof(int), typeof(RadialPanel));
Routed events syntax:
MSDN documentation
ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETFX30SDK4VS.1033/wpf_conceptual/html/1a2189ae-13b4-45b0-b12c-8de2e49c29d2.htm
// routed event
public static readonly RoutedEvent EventNameEvent = EventManager.RegisterRoutedEvent("EventName",
RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyEnclosingClass));
// A .NET event wrapper (optional)
public event RoutedEventHandler EventName
{
add { AddHandler(EventNameEvent, value); }
remove { RemoveHandler(EventNameEvent, value); }
}
{
...
RaiseEvent(new RoutedEventArgs(EventNameEvent, this));
...
}
Binding syntax:
FAQ on Binding from MSDN blog:
http://blogs.msdn.com/wpfsdk/archive/2006/10/19/wpf-basic-data-binding-faq.aspx
NOTE: Can’t seem to nest bindings, e.g. {Binding Source={Binding Source={StaticResource resourceName}}}
NOTE: Target property (i.e. the left-hand side of {Binding...} must be a dependency property.
NOTE: When the source property is not a dependency property, the target property won’t be updated as the source property changes. To get them to be synchronized, the source object needs to either 1) implement the System.ComponentModel.INotifyPropertyChanged interface which has the single PropertyChanged event, or 2) implement an XXXChanged event, where XXX is the name of the property whose value changed. (first approach is recommended)
// ElementName used to refer to a XAML element defined by x:Name and source property on that object accessed through property1.property2
{Binding ElementName=elementName, Path=property1.property2}
{Binding property1.property2, ElementName=elementName}
// ElementName used to refer to a XAML element defined by x:Name
{Binding ElementName=elementName}
// Source used to refer to data source defined in ResourceDictionary and source property on that object accessed through property1.property2
{Binding Source={StaticResource resourceName}, Path=property1.property2}
// Source used to refer to data source defined in ResourceDictionary
{Binding Source={StaticResource resourceName}}
// when used within a FrameworkElement/FrameworkContentElement that have the DataContext property set to some data source, all nested Binding references implicitly assume a Source property value equal to that DataContext
<StackPanel DataContext={StaticResource resourceName}>
<Label Content={Binding Path=property}/>
<ListBox ItemsSource={Binding}/>
</StackPanel>
// when used within a DataTemplate, the DataContext is automatically set to the appropriate Source object, i.e. for ItemTemplate, it’s the current item
<ListBox>
<ListBox.ItemTemplate>
<Image Source=“{Binding Path=property}”/>
</ListBox.ItemTemplate>
</ListBox>
Binding’s RelativeSource property syntax:
RelativeSource property of Binding can be used to refer to data source relative to the target element
// source element equals target element
<Binding RelativeSource={RelativeSource Self}>
// source element equals target element’s TemplatedParent, which is essentially the target element of the template
<Binding RelativeSource={RelativeSource TemplatedParent}>
// source element equals the closest parent of a given type
<Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type desiredType}}>
// source element equals the nth closest parent of a given type
<Binding RelativeSource={RelativeSource FindAncestor, AncestorLevel=n, AncestorType={x:Type desiredType}}>
// source element equals the previous data item in a data-bound collection
<Binding RelativeSource={RelativeSource PreviousData}}>
TemplateBinding syntax:
Data source for TemplateBinding is always the target element, and the path is any of its dependency properties.
TemplateBinding can’t be used outside of a template’s VisualTree property, so can’t use in a trigger. Instead, you can use {Binding RelativeSource={RelativeSource TemplatedParent}}
<ControlTemplate TargetType=“{x:Type Button}”>
<!-- following bindings are all the same -->
<TextBlock Text=“{TemplateBinding Property=Button.Content}”/>
<TextBlock Text=“{TemplateBinding Button.Content}”/>
<TextBlock Text=“{TemplateBinding Content}”/>
</ControlTemplate>
ValueConverter syntax:
<Application.Resources>
<local:SingleConverter x:Key=“converter1”/>
<local:MultiConverter x:Key=“converter2”/>
</Application.Resources>
// single binding
<Label Background=“{Binding Source={StaticResource source}, Path=property, Converter={StaticResource converter1}, ConverterParameter=parameter}”/>
public class SingleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
...
}
}
// multibinding
<ProgressBar ...>
<ProgressBar.Value>
<MultiBinding Converter=“{StaticResource converter2}, ConverterParameter=parameter”>
<Binding ...}”/>
<Binding ...}”/>
<Binding ...}”/>
</MultiBinding>
</ProgressBar.Value>
</ProgressBar>
public class MultiConverter : IMultiConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
object value1 = values[0];
object value2 = values[1];
...
}
}