Windows Presentatiion Foundation (WPF)

This page is a listing of WPF and XAML development tips.

Q: How do I bind a TextBlock control to a variable?

A: In WPF, you cannot bind to a variable, only to a property.

1. Set a DataContext for this window or user control. Data binding is done to whatever the DataContext property is set equal to. This can be done in two ways:

a. In the View constructor (.xaml.cs), manually assign it in code

this.DataContext = <some object>

b. Assign the DataContext via XAML. This can be done in several ways.

i. Within the UserControl block, add a UserControl.DataContext element, for example:

<UserControl.DataContext>

<Binding Source="{StaticResource ViewModel}" />

</UserControl.DataContext>

2. In WPF, binding occurs to members of the DataContext. If the property you wish to bind to is not a member of the DataContext, or member of a member, you can't bind to it.

3. Set the Text attribute of the XAML for this control to reference the member of the DataContext to bind for display. For example, assume DataContext is equal to a class with a public member called CurrentContainerPath. To bind to dataContext.CurrentContainerPath, set or change the Text attribute as follows:

Text="{Binding Path=CurrentContainerPath}"

Q: I bound a control to a property member, but when the member is changed, the GUI is not updated. How do I fix this?

A: When the member changes, you must call RaisePropertyChanged with the name of the member. This means that practically, the member must be a property. Also, the DataContext, the object containing the property, must implement System.ComponentModel.INotifyPropertyChanged.

Q: I am adding a large number (>100) items to an ObservableCollection bound to the GUI and it is taking noticeable time and significant CPU. How do I eliminate this?

A: This is due to the design of ObservableCollection. To resolve this, suppress the collection changed notifications generated when each item is added. There are two ways to do this:

1. Switch to a System.ComponentModel.BindingList and suppress list change notifications by setting RaiseListChangedEvents = false before adding them items.

2. Create a new class derrived from IObservableCollection with a new AddBulk member and overriding OnCollectionChanged. In AddBulk, set a flag indicating that AddBulk is being called. In OnCollectionChanged, do not call base.OnCollectionChanged if that flag is set.

See this article for more information: http://stackoverflow.com/questions/57020/which-net-collection-for-adding-multiple-objects-at-once-and-getting-notified

Q: How do I debug a binding that is not working? There is no error, but no data is showing up in WPF.

A: Follow these steps:

1. Add the following to the Window or User control element at the root of the XAML:

xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"

2. Find the XAML binding that you are having trouble with and set it's TraceLevel=high by adding diag:PresentationTraceSources.TraceLevel=High to the binding spec. For example:

<t:DataGridTextColumn Header="Filename" Width="250" Binding="{Binding Path=name, diag:PresentationTraceSources.TraceLevel=High}"/>

3. Build and run your application. The binding log messages will appear in the Output window. Messages indicating "got raw value {DependencyProperty.UnsetValue}" mean the source property is null. It may not have been set before InitializeComponents was called.

If this is a Release-mode application that you cannot run under a debugger, enable trace logging by editing the app.config of your EXE and adding the following within the configuration block. The trace filename is specified via system.diagnostics\sharedListeners\add.initializeData attribute, c:\Debug.txt in this case.

<system.diagnostics>

<sources>

<source name="System.Windows.Data" switchName="SourceSwitch" >

<listeners>

<add name="textListener" />

</listeners>

</source>

</sources>

<switches>

<add name="SourceSwitch" value="All" />

</switches>

<sharedListeners>

<add name="textListener"

type="System.Diagnostics.TextWriterTraceListener"

initializeData="c:\\DebugTrace.txt" />

</sharedListeners>

<trace autoflush="true" indentsize="4"></trace>

</system.diagnostics>

Other tricks:

1. Put a breakpoint in the property getter

2. Create a value converter that simply returns the value it was given, then use it in a particular binding of interest and put a breakpoint in the converter.

Q: My binding displays no data, but the path and syntax are correct. How do I fix this?

A: If you are sure the Binding syntax is correct, most likely you are referring to a data member of an object instead of a Property. WPF requires properties. To verify this, enable WPF binding tracing as shown above, then check the trace file for a message like this:

System.Windows.Data Error: 39 : BindingExpression path error: 'name' property not found on 'object' ''MyItemClass' (HashCode=25292115)'. BindingExpression:Path=name; DataItem='MyItemClass' (HashCode=25292115); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

This message illustrates a binding failure because the target is a data member and not a property. Also, note that WPF cannot bind to private properties.

Q: How do I create a custom text display of a bound object?

A: There are two ways to do this: via an IValueConverter object, the most powerful way, and via the StringFormat Binding option, new in NET 3.5 SP1. The later is appropriate to most simple cases.

For the IValueConverter approach, you must write an IValueConverter to convert your class to text, then declare the converter in the XAML, and hook it up to the binding.

To declare the converter in the XAML, add it to the Resources as a v: type with an x:Key equal to the name of your class. The v: key may also need to be the same as the class name. For example:

<UserControl.Resources>

<v:HideOnEmptyConverter x:Key="HideOnEmptyConverter" />

To hookup the converter, refer to the XAML static resource in the Binding attribute of your tag. In this example, the entire DataContext object is passed in, not a member of it.

<TextBlock Text="{Binding Converter={StaticResource TagDescriptionConverter}}" Margin="4 0">

The IValueConverter only needs to implement Convert. ConvertBack can do nothing. In Convert, check the type of the object and return your custom string representation, like this:

public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )

{

Repository.Interface.Tag valueAsTag;

if (value is Repository.Interface.Tag)

{

valueAsTag = (Repository.Interface.Tag) value;

return String.Format("{0}={1},", valueAsTag.Name, valueAsTag.Value);

}

else

{

return "";

}

Q: How do I format a numeric value displayed?

A: There are two ways to do this:

1. Write a value converter. See the above question "In WPF, how do I create a custom text display of a bound object?" for how.

2. Use the StringFormat Binding option, new to NET 3.5SP1.

Q: How do I display a file size (number) with commas?

A: Append StringFormat=N0 to your Binding string, as in:

Binding="{Binding Info.Size, StringFormat=N0}"

Q: How do I implement sorting for my DataGrid?

A: There are two ways to do so: via XAML automatic support and custom sorting. To implement custom sorting:

1. In the DataGrid XAML, set CanUserSortColumns="True"

2. In the column XAML, set CanUserSort="True" for each column where sorting can be done.

3. Write a model/ViewModel function to sort the collection the DataGrid is bound to and set a default for sorting (none/asc/desc).

4. Write a function to respond to clicks on the DataGrid's column headers and request sorting. This function must:

a. Set eventArgs.Handled = true

b. Set the SortDirection for the column. WPF does not automatically set the sort direction when the column is clicked, or change directions. eventArgs.Column is a reference to the column itself, so use eventArgs.Column.SortDirection to get/set this.

c. Note that SortDirection is nullable since a column may not have a sort direction set. Sorting thus can be three state. If you do not want three state sorting, set a default SortDirection on each column in the XAML via SortDirection.

d. Finally, it must call the model/viewmodel sort function created in step 3.

5. On the DataGrid, set Sorting="<name of GUI handler function from #4>" This hooks up the standard click-on-column-header-to-sort UI.

Q: How do I display file sizes calculated and described in standard units, like KB, MB, GB?

A: Implement the following custom converter, declare it in XAML and use it in the binding to your numeric value. See this question for how to make the two XAML support changes.

class FileSizeConverter : IValueConverter

{

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)

{

string[] units = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };

double size = (long)value;

int unit = 0;

while (size >= 1024)

{

size /= 1024;

++unit;

}

return String.Format("{0:0.#} {1}", size, units[unit]);

}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

{

throw new NotImplementedException();

}

}

Q: How do I use literals in the display of a WPF data binding?

A: Use the StringFormat option. {0} refers to the string value of this field.

If your format string starts with {0}, you must start it in one of two ways, or WPF will reject it.

1. Start the string with {}, as in: (RECOMMENDED)

<TextBlock Text="{Binding Info.Size, StringFormat={}{0} bytes}" />

2. An opening parenthesis, as in:

<TextBlock Text="{Binding Info.Size, StringFormat=({0} bytes}" />

If the format starts with the string literal, just enter it directly, as in:

<TextBlock Text="{Binding Info.Size, StringFormat=The size is {0} bytes}" />

Q: How do I bind a WPF control to multiple fields?

A: Specify the Text element using a MultiBinding. For example:

<TextBlock>

<TextBlock.Text>

<MultiBinding StringFormat="({0}, {1:N0} bytes">

<Binding Path="RepositoryFullPathname" Mode="OneWay"/>

<Binding Path="Info.Size" Mode="OneWay"/>

</MultiBinding>

</TextBlock.Text>

</TextBlock>

Q: How do I set the alignment of the text displayed within a DataGrid column?

A: Set the TextBlock.TextAlignment attribute of the Column's CellStyle using a Style tag. For example:

<t:DataGridTextColumn.CellStyle>

<Style>

<Setter Property="TextBlock.TextAlignment" Value="Right"/>

</Style>

</t:DataGridTextColumn.CellStyle>

Q: In an event handler, how can I change what is shown on the UI during processing?

A: WPF is built with the assumption that the GUI will not need to update during event handlers. A straightforward way to resolve this is to split your logic at UI update boundaries, then post callbacks to complete the next logical action by using a DispatcherFrame that runs *on idle*. Use a dispatcher *on a GUI object* for this to work. For example, say you want to hide one control and show another during a time-consuming operation, then switch then back on completion. Divide the logic at the hide/show. The hide/show goes in the normal view event handler, and the time-consuming operation and switch back go in a Dispatch

private void OnAddTagClick(object sender, RoutedEventArgs e)

{

entityGrid.Visibility = System.Windows.Visibility.Collapsed;

waitForSearch.Visibility = System.Windows.Visibility.Visible;

entityGrid.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.ApplicationIdle, new GuiWorker(AddFilterTagWorker));

}

public delegate void GuiWorker();

public void AddFilterTagWorker()

{

viewModel.AddFilterTag(tagBox.Text);

waitForSearch.Visibility = System.Windows.Visibility.Collapsed;

entityGrid.Visibility = System.Windows.Visibility.Visible;

}

If you schedule the worker to run at Normal priority, the GUI will not update until the time-consuming AddFilterTag call completes.

This can also be resolved with two other methods not detailed here: dispatcher frames and forced GUI updates.

See also, possible alternate non-cannon solution: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/6fce9b7b-4a13-4c8d-8c3e-562667851baa/

And one other potential solution that is canon: http://geekswithblogs.net/NewThingsILearned/archive/2008/08/25/refresh--update-wpf-controls.aspx

Q: How do I handle a row double-click event on a DataGrid?

A: Use these steps:

1. Add a MouseDoubleClick handler to the DataGrid

2. In the event handler, use ContainerFromElement to map the click to the row clicked on, as this handler will receive *all* DataGrid double-clicks, including those in empty space, borders, and the headers. For example:

private void DataGrid_MouseDoubleClick( object sender, MouseButtonEventArgs e )

{

Microsoft.Windows.Controls.DataGridRow gridRow = null;

Repository.Interface.Entity rowEntity = null;

// Did the user double click on a row?

gridRow = ItemsControl.ContainerFromElement((Microsoft.Windows.Controls.DataGrid) sender, e.OriginalSource as DependencyObject) as Microsoft.Windows.Controls.DataGridRow;

if (gridRow != null)

{

rowEntity = gridRow.Item as Repository.Interface.Entity;

// Do something useful with rowEntity

}

Q: In my DataGrid, how do I display a different image based on the type of an item?

A: This is supported through the DataGridTemplateColumn, but not well documented. If the image can be determined by a boolean field, use the following example column definition. In this example, the Item type has a boolean field named "Exists" and the image is stored in another assembly.

<t:DataGridTemplateColumn Header="Icon" Width="50" CanUserResize="False" CanUserSort="False">

<t:DataGridTemplateColumn.CellTemplate>

<DataTemplate>

<Image Name="img" Width="16" Height="16"/>

<DataTemplate.Triggers>

<DataTrigger Binding="{Binding Exists}" Value="true">

<Setter TargetName="img" Property="Source" Value="/Common;component/Resources/ButtonIcons/folderClosed.png"/>

</DataTrigger>

<DataTrigger Binding="{Binding Exists}" Value="false">

<Setter TargetName="img" Property="Source" Value="/Common;component/Resources/ButtonIcons/documents.png"/>

</DataTrigger>

</DataTemplate.Triggers>

</DataTemplate>

</t:DataGridTemplateColumn.CellTemplate>

</t:DataGridTemplateColumn>

Q: How do I add an image control in XAML?

A: Use the Image element with the full pathname to the file. If not specified, width and height are extracted from the size of the image resource. This example shows an image where the file exists in another assembly called Common. Note that in such a case, the path prefix "component/" is required to resolve resources in the root of the specified assembly.

<Image Source="/Common;component/Resources/ButtonIcons/folderClosed.png" Width="16" Height="16"></Image>

Q: How do I force update a control's binding?

A: Get the control's binding expression, then call Update target. This requires access to the dependency property. For example:

var bindingExpression = uiTextBlock.GetBindingExpression(TextBlock.TextProperty);

bindingExpression.UpdateTarget();

Q: How do I bind directly to the view, the class backing a XAML-defined dialog?

A: Set DataContext = this in the class constructor and write bindings as you normally would.

Q: How do I display multiple controls for a single item?

A: For example, say your DataContext has a property named Tags with fields Name and Value. To display them both in a single ListBox item, use the following XAML. The Grid element is unnecessary.

<ListBox Grid.Row="1" ItemsSource="{Binding Tags}">

<ItemsControl.ItemTemplate>

<DataTemplate>

<StackPanel>

<TextBlock Text="{Binding Name}"/>

<TextBlock Text="{Binding Value}"/>

</StackPanel>

</DataTemplate>

</ItemsControl.ItemTemplate>

</ListBox>

Q: How do I get the selected item(s) in a ListBox?

A: If the ListBox is single select, use .SelectedItem. Otherwise, you must query each ListBox item. See http://blogs.msdn.com/b/andrewarnottms/archive/2007/09/05/how-to-find-the-focused-listboxitem-in-wpf.aspx for how. For multi-select, if the ListBox does not have focus, this method may not work.

Q: How do I get the target item in a click on a button in a ListBox item using an ItemsControl.ItemTemplate?

A: Bind the button to the item, then cast the sender object in the event handler to the appropriate control type and use the DataContext. For example:

XAML:

<Button Click="OnDeleteTag" DataContext="{Binding}">

Event handler (OnDeleteTag here):

var senderControl = sender as System.Windows.Controls.Button;

var targetTag = senderControl.DataContext as Repository.Interface.Tag;

Q: I got a bizzare error from my XAML stating that a the tag backing a class doesn't exist, but I know it does. Why is my build breaking? The error looks like:

App.xaml(13,14): error MC3074: The tag 'DataTranslationControl' does not exist in XML namespace 'clr-namespace:Cybernet.Vsil.Vise.DataTranslatorWizard.View;assembly=DataTranslatorWizard'. Line 13 Position 14.

A: The assembly backing the control does not exist or can't be built. Review the build output for a warning on the assembly hosting this control or a dependant one that it lacks a reference to a dependent assembly, then add it to the relevant assembly and the build should complete.

Q: I added the display of a child dialog to a window, but now the application seems to hang on exit sometimes. Why?

A: Call .Close on the child dialog even if not shown. WPF believes the dialog may still be visible somewhere and is waiting for it to close before allowing the application to close. The window is cleaned up if ShowDialog is called, but not if it isn't called.

Q: How do I display some text in a TextBlock as bold, but not all?

A: Use a Span tag to specify the bold part, as in:

<TextBlock >This is the normal part and <Span FontWeight="Bold">this is the bold part</Span>inside the normal font sent.</TextBlock>

Q: In an ItemsControl DataTemplate, how do I bind a control to a value from the object that the ItemsControl is referring to?

A: Bind the Tag attribute of the ItemsControl to this object, then use a RelativeSource-type binding in your DataTemplate control to find the ItemsControl's Tag. For example, assume the following:

1. You have a class named RepositoryInfo with the following fields:

string Name

string ServerUri

2. The ViewModel exposes the following properties:

RepositoryInfo CurrentRepository

BindingList<RepositoryInfo> KnownRepositories

3. You have an ItemsControl bound to KnownRepositories

<ItemsControl ItemsSource="{Binding KnownRepositories}">

To bind a TextBlock in the ItemsControl's DataTemplate to show the name of the current repository, do the following:

1. Add the following tag to the ItemsControl

Tag="{Binding CurrentRepository}"

2. Add the following TextBlock to the DataTemplate

<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=ItemsControl,AncestorLevel=1,Mode=FindAncestor}, Path=Tag.Name}" Margin="8 0 8 0">

Q: How do I bold the text of a control in item in an ItemsControl based on a property in my ViewModel?

A: For example, assume the following:

1. You have a class named RepositoryInfo with the following fields:

string Name

string ServerUri

2. The ViewModel has a property RepositoryInfo CurrentRepository and a BindingList<RepositoryInfo> KnownRepositories

To do this in WPF, you must bind the CurrentRepository property to a value on the ItemsControl, use a multibinding to refer to both the current item and the ItemsControl's Tag, write a MultiValue converter to convert the pair to a font weight, and finally bind FontWeight using the multibinding with the MultiValue converter. To do this:

1. Bind the Tag of the ItemsControl to CurrentRepository by adding the following attribute to it:

Tag="{Binding CurrentRepository}"

2. Write an IMultiValueConverter that compares two values and returns FontWeights.Bold if equal, else FontWeights.Normal:

public class ComparisonToFontWeightConverter : IMultiValueConverter

public object Convert( object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture )

// Compare values[0] and values[1]

if (values[0] != values[1])

return System.Windows.FontWeights.Normal;

else

return System.Windows.FontWeights.Bold;

public object[] ConvertBack( object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture )

throw new NotImplementedException();

3. Bind the FontWeight property of the text control to both CurrentRepository and the current item value:

<TextBlock Text="{Binding Name}" Margin="8 0 8 0">

<TextBlock.FontWeight>

<MultiBinding Converter="{StaticResource ResourceKey=ComparisonToFontWeightConverter}">

<Binding Path="{}"></Binding>

<Binding RelativeSource="{RelativeSource AncestorType=ItemsControl,AncestorLevel=1,Mode=FindAncestor}" Path="Tag"></Binding>

</MultiBinding>

</TextBlock.FontWeight>

</TextBlock>

Q: How do I do refer to the item that was clicked on in the ContextMenu handler of an ItemsControl?

A: Make sure the ContextMenu is defined in the context of the ItemContainer style to bind the menu's DataContext to the current item in the ItemsControl. Then write an on-clicked handler like this:

private void MyDelete_Click( object sender, RoutedEventArgs e )

var senderControl = sender as System.Windows.FrameworkElement;

RepositoryInfo itemRepositoryInfo;

itemRepositoryInfo = senderControl.DataContext as RepositoryInfo;

System.Windows.MessageBox.Show(System.Windows.Application.Current.MainWindow, "You selected "+itemRepositoryInfo.Name);

KnownRepositories.Remove(itemRepositoryInfo);

Q: How do I determine which item was double-clicked on in a WPF ItemsControl MouseDoubleClick handler?

A: NOTE: This answer is out of date with respect to "How do I do refer to the item that was clicked on in the ContextMenu handler of an ItemsControl?" See this question for guidance on a better answer.

Bind the Tag property of the control to {Binding} to bind it to them item, then reference OriginalSource.Tag member of MouseButtonEventArgs. For example:

<Image Name="RepositoryIcon" Source="{StaticResource DatabaseConnectedIcon}" Tag="{Binding}"/>

With the following handler in the XAML's View:

private void OnRepositoryControlDoubleClick( object sender, MouseButtonEventArgs eventArgs )

Repository.RepositoryInfo clickedRepository = null;

clickedRepository = eventArgs.OriginalSource as RepositoryInfo;

if (clickedRepository != null)

viewModel.LoginToSpecificRepository(clickedRepository);

Q: I'm getting a strange XAML parse error in my WPF application, but I know my XAML is not the cause of this problem. What is going on?

A: Disable the native debugger. Either go to Tools|Options|Debugging|Just-in-time and uncheck Native or go to Project Options|Build and uncheck Enable unmanaged code debugging. When the native debugger is enabled, WPF swallows the actual exception and generates a generic "XAML creation error" exception, since the error occured while constructing the object, in it's place.

Q: In a DataGrid, how do I make it possible to hide the row details?

A: Follow these instructions:

1. Set the default visibility to Collapsed.

2. Add a DataGrid.SelectionChanged handler with the following code:

private void OnEntitySelection(object sender, SelectionChangedEventArgs e)

if (e.RemovedItems.Count == 1)

{

if (entityGrid.GetDetailsVisibilityForItem(e.RemovedItems[0]) == System.Windows.Visibility.Visible)

entityGrid.SetDetailsVisibilityForItem(e.RemovedItems[0], System.Windows.Visibility.Collapsed);

}

if (entityGrid.SelectedItem != null)

{

if (entityGrid.GetDetailsVisibilityForItem(entityGrid.SelectedItem) == System.Windows.Visibility.Visible)

entityGrid.SetDetailsVisibilityForItem(entityGrid.SelectedItem, System.Windows.Visibility.Collapsed);

else

entityGrid.SetDetailsVisibilityForItem(entityGrid.SelectedItem, System.Windows.Visibility.Visible);

}

3. Add a button to the row details to hide the details

entityGrid.SetDetailsVisibilityForItem(entityGrid.SelectedItem, System.Windows.Visibility.Collapsed);

Q: The Visual Studio designer cannot display my XAML when I refer to a type defined inside a class using the + operator. The project builds and runs correctly, however. How do I fix this?

A: Move the type outside of the class or write a custom markup extension to get the type. This is a known bug in the Visual Studio 2010 WPF designer. See http://social.msdn.microsoft.com/Forums/en/wpf/thread/12f3e120-e217-4eee-ab49-490b70031806

Q: How do I bind an enum to a ComboBox (or other Items controls), but display user friendly descriptions of the values?

A: Follow these instructions:

1. Tag each enum value with a System.ComponentModel.Description attribute with the description to show in the GUI.

2. Write a value converter that converts an enum->description and description->enum value. For Convert, cast value to an Enum, then use reflection to get the DescriptionAttribute.

3. Declare the value converter in the XAML Resources section, making it available for use there. For example:

<v:EnumDescriptionConverter x:Key="EnumDescriptionConverter" />

4. Declare a list the enum values in the XAML. This can be dynamiclaly determined by using ObjectDataProvider as shown below. Note that due to a bug in the Visual Studio WPF Designer, the enum type must not be defined within a class, it must be directly within the specified namespace.

<ObjectDataProvider MethodName="GetValues"

ObjectType="{x:Type sys:Enum}"

x:Key="SourceTypeValues">

<ObjectDataProvider.MethodParameters>

<x:Type TypeName="vm:SourceType" />

</ObjectDataProvider.MethodParameters>

</ObjectDataProvider>

5. Bind the ComboBox's Items source to the enum value list provider created in step 4. This sets the list of items for the ComboBox's list control to the enum values.

<ComboBox ItemsSource="{Binding Source={StaticResource SourceTypeValues}}" ...>

6. Bind the ComboBox's SelectedItem to the DataContext field to bind.

<ComboBox SelectedItem="{Binding DataSourceType}" ...>

7. Finally, provide a DataTemplate using the value converter defined in step 2. This displays each enum using the description attribute and sets SelectedItem to the value selected.

<ComboBox ...>

<ComboBox.ItemTemplate>

<DataTemplate>

<TextBlock Text="{Binding Converter={StaticResource EnumDescriptionConverter}}"/>

</DataTemplate>

</ComboBox.ItemTemplate>

</ComboBox>

Q: I am getting an exception 'IValueConverter' type does not have a public TypeConverter class. Why?

A: You are referring to a value converter with incorrect syntax, lacking the enclosing braces. For example, this XAML generates this error:

<Binding Path="Foreground" Converter="StaticResource BrushToRgbConverter"/>

But this is valid

<Binding Path="Foreground" Converter="{StaticResource BrushToRgbConverter}" />

Add need the following braces: ^^^ ^^^

Q: How do I use resources from another assembly?

A: This requires two steps. The MSDN examples are incorrect.

1. In the .Resources section for the Window or UserControl, declare an unnamed ResourceDictionary and use the MergedDictionaries directive with the path to the XAML to merge in. The path must specify the assembly name and relative path within the assembly in the following format: /<assemblyName>;component/<assemblyPath>/<XAML filename with extension>.

2. Define all other resources for this window/user control within that ResourceDictionary tag.

For example:

<UserControl.Resources>

<!-- When using MergedDictionaries, locally defined resources must be within the ResourceDictionary tag -->

<ResourceDictionary>

<ResourceDictionary.MergedDictionaries>

<ResourceDictionary Source="/Common;component/Themes/Generic.xaml"/>

</ResourceDictionary.MergedDictionaries>

<v:HideOnEmptyConverter x:Key="HideOnEmptyConverter" />

<v:ShowOnEmptyConverter x:Key="ShowOnEmptyConverter" />

...

</ResourceDictionary>

</UserControl.Resources>

Q: When I use the Visual Studio Designer on a XAML file using a custom markup extension, I get an exception like this:

System.Windows.Markup.XamlParseException Cannot add element to ; the property value is null.

A: The custom XAML extension has an uninitialized public property. Most often, this is a collection type that was not initialized in the constructor. Note that autogenerated object/collection properties are initialized to null, not an instance of the specified type.

Q: How do I refer to a nested class or type definition in XAML? ContainingClass.InnerClass does not work.

A: Use the syntax ContainingClass+InnerClass instead. Note that while WPF and Expression Blend support nested classes, the VS2010 earlier visual designers do not as of 2011 May 18, but Microsoft is considering fixing this. See:

http://connect.microsoft.com/VisualStudio/feedback/details/361509/xaml-designer-cannot-handle-typename-with-nested-classes

http://connect.microsoft.com/VisualStudio/feedback/details/605614/xaml-designer-x-static-nexted-type-error-type-ns-class-nestedclass-was-not-found

http://social.msdn.microsoft.com/Forums/en/vswpfdesigner/thread/098c8b12-e85b-49d3-9d0b-672f1d325c6e

Q: How do I use a nested class as a value converter?

A: There are two ways:

1. Implement a public static function in a non-nested class that returns an instance of the nested class. For example:

public class Foo

{

public static MyConverter Converter { get { return new MyConverter(); } }

public class MyConverter : IValueConverter

{

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

{

return Double.Parse(value.ToString()) + 50.0d;

}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

{

throw new NotImplementedException();

}

}

}

Then refer to it using standard XAML:

<Label Content="{Binding Path=Width, RelativeSource={RelativeSource Self}, Converter={x:Static local:Foo.Converter}}"/>

2. Refer to the class using proper nested class syntax. Use a + character to separate the containing class name from the inner class. Note that this is compatible with XAML, but the Visual Studio 2010 designer does not handle it well. Also, WPF in general has difficulties in areas with nested classes due to it's assumption that the "." separator always separates a class name from a property name in binding syntax.

Q: I tried to bind Window.Top, Bottom, Width, Height to a property but it does not work. WPF picks up the value once and never again, although the PropertyChanged handler is being called. Why?

A: The property bound to must have both a get and set and the binding mode must be specified as Two-Way for this to work. WPF allows each property of a control to have a different default binding mode. The default binding mode for window location properties is one-way, even thought they require a two-way binding to work as intended with a binding.

Q: My application throws a XamlParseException - can't locate resource when trying to use a XAML file defined in another assembly, but my syntax looks correct.

A: The correct syntax is exactly "/<Assembly name>;component/<xaml filename or path to it>". For example, "/GuiUtil;component/Common.xaml" is the path for a file named Common.xaml in the root of assembly GuiUtil. The prefix "component/" is a reserved prefix that is required for all resources.

Q: In WPF, I get this error when I try to start my program:

System.Windows.Markup.XamlParseException' occurred in PresentationFramework.dll:

Additional information: 'String' object cannot be added to 'DataGrid'. Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead. Error at object 'MyGrid' in markup file 'TestApp;component/mainwindow.xaml' Line 23 Position 34.

A: There are many possible causes. Check the XAML for additional > characters after end tags. This is caused by invalid XAML syntax that the XAML editor did not flag. For example, the following XAML has an extra > on the 4th line after it's close tag and causes this error.

<t:DataGrid Name="MyGrid" ItemsSource="{Binding testData}" AutoGenerateColumns="False" Margin="0,0,161,32">

<t:DataGrid.Columns>

<t:DataGridTextColumn Header="Value" Binding="{Binding Value,Mode=OneWay}" />

</t:DataGrid.Columns> >

</t:DataGrid>

Q: In WPF, how do I display a bound collection as sorted without changing the underlying collection to a sorted collection?

A: Use the SortDescriptions on a CollectionView. WPF provides view sorting, current record support, and filtering via a ICollectionView-based classes. There are two ways to implement this:

1. Use the default view for the collection

WPF automatically creates a view object for every collection it binds to. To access it in code, call the static method CollectionMethod.GetDefaultView() for the collection property that the control is bound to. This default collection cannot be directly accessed in XAML, but you can accomplish the needed effect by using method #2.

2. Create a custom view

To create a custom view in code:

A. Add a ListCollectionView or BindingListCollectionView to the DataContext (ViewModel or model). Pass the collection to be sorted/filtered/etc in the constructor,

B. Bind the control to the new *CollectionView property instead of the old collection property.

To create a custom view in XAML, you must create a CollectionView static resource, bind it to your data, and bind the control to that instead. For example, if the source data is declared in a static resource, this example sorts ListBox items by City, then State by binding it to a

<Window.Resources>

<src:Places x:Key="places"/>

<CollectionViewSource Source="{StaticResource places}" x:Key="cvs">

<CollectionViewSource.SortDescriptions>

<scm:SortDescription PropertyName="CityName"/>

</CollectionViewSource.SortDescriptions>

<CollectionViewSource.GroupDescriptions>

<dat:PropertyGroupDescription PropertyName="State"/>

</CollectionViewSource.GroupDescriptions>

</CollectionViewSource>

</Window.Resources>

<ListBox ItemsSource="{Binding Source={StaticResource cvs}}"

DisplayMemberPath="CityName" Name="lb">

<ListBox.GroupStyle>

<x:Static Member="GroupStyle.Default"/>

</ListBox.GroupStyle>

</ListBox>

Q: How do I display a WPF GUI window from a worker thread?

A: Create a public static method in the GUI window that does the following:

1. Creates a new System.Threading.Thread object

2. Startup method creates the window, shows the window, runs Dispatcher.InvokeShutdown() on Closed, and runs the Dispatcher.

3. Set the Apartment state of the GUI thread to STA

4. Start the thread

An example follows. Note in this case, the GUI thread must save a new GUI object in the scope of the worker thread so the worker can access it. The two threads synchronize on this action via a event object. Also note that the worker cannot call most methods on this object directly or WPF will throw because the object is called from outside it's GUI thread.

public static ConsoleWindow CreateOwnGuiThread()

{

ConsoleWindow newConsoleWindow = null;

System.Threading.AutoResetEvent consoleCreated = new System.Threading.AutoResetEvent(false);

System.Threading.Thread guiThread = new System.Threading.Thread( () =>

{

newConsoleWindow = new ConsoleWindow();

// Stop message pump when window is closed

newConsoleWindow.Closed += (senderB, eventB) => {newConsoleWindow.Dispatcher.InvokeShutdown();};

newConsoleWindow.Show();

// Notify the parent worker that we've initialized

consoleCreated.Set();

// Run message pump

System.Windows.Threading.Dispatcher.Run();

}

);

// GUI threads must run in STA

guiThread.SetApartmentState(System.Threading.ApartmentState.STA);

guiThread.Start();

// Wait for worker GUI thread to initialize

consoleCreated.WaitOne();

return newConsoleWindow;

}

For reference, see http://eprystupa.wordpress.com/2008/07/28/running-wpf-application-with-multiple-ui-threads/.

Q: How do I force refresh a GUI element during a method handler?

A: Ask the dispatcher to run a NOP delegate at Background priority. This will cause it to process all pending operations of equal or greater priority first, updating the window. For example:

System.Windows.Threading.DispatcherFrame frame = new System.Windows.Threading.DispatcherFrame();

System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Background,

new Func<Object, Object>((arg) => {

((System.Windows.Threading.DispatcherFrame)arg).Continue = false;

return null;

}), frame);

System.Windows.Threading.Dispatcher.PushFrame(frame);

Q: How do I specify a Tooltip for a DataGrid Text Column?

A: Convert the text column to a Template column, specify the bound control to display the column for each row, then set the Tooltip member of that control. To use a basic text tooltip, just set Tooltip=. This property is also a content property, so to use a custom tooltip, set the property directly. For example, convert this column definition:

<t:DataGridTextColumn Header="Name" Binding="{Binding Info.Name}" Width="Auto" CanUserSort="True">

To this:

<t:DataGridTemplateColumn.CellTemplate>

<DataTemplate>

<TextBlock Text="{Binding Info.Name, Mode=OneWay}" ToolTip="{Binding Info.Name}">

</TextBlock>

</DataTemplate>

</t:DataGridTemplateColumn.CellTemplate>

To display a fully custom tooltip window, set the ToolTip property using this syntax:

<TextBlock Text="{Binding Info.Name, Mode=OneWay}">

<TextBlock.ToolTip>

<Border CornerRadius="3" BorderThickness="4" HorizontalAlignment="Left" VerticalAlignment="Top" Width="325" Height="90">

<Grid>

// Neat stuff goes here, DataContext is an element in the DataGrid Items collection

</Grid>

</Border CornerRadius="3" BorderThickness="4">

</TextBlock.ToolTip>

</TextBlock>

In this case, it may be advisable to disable the default shadow by encapsulating the TextBlock.ToolTip children in the following element:

<ToolTip HasDropShadow="False" Background="{x:Null}" BorderBrush="{x:Null}">

</ToolTip>

See http://www.cnblogs.com/sheva/archive/2006/08/24/485790.html.

Q: How do I create a property of a custom control where I can assign a value to it using {binding} syntax?

A: You must make the property a dependency property. To do so:

1. Declare a property identifier. These are typically public because they are readonly and may be used by other code to construct binding expressions, but they do not have to be. The textual name specified for the property in the registration should match the name of the property on the control in step 2.

public static readonly DependencyProperty Property_ReferenceTime = DependencyProperty.Register("referenceTime", typeof(DateTime), typeof(TimerTextBlock), new UIPropertyMetadata(DateTime.Now));

2. Add a public property to the control class. Use GetValue/SetValue to get and set the property value, and call RaisePropertyChanged to notify WPF of changes to the property value:

public DateTime referenceTime

{

get

{

return (DateTime) GetValue(Property_ReferenceTime);

}

set

{

SetValue(Property_ReferenceTime, value);

RaisePropertyChanged("referenceTime");

}

}

Q: What are the format strings to convert a TimeSpan to a string?

A: There are none in NET 3.5. To workaround this, convert the TimeSpan to a DateTime, then use the DateTime format strings. For example:

TimeSpan myTimeSpan

DateTime tsAsDateTime = new DateTime(myTimeSpan.Ticks);

Q: How do I call a GUI window method periodically, in response to a timer?

A: Use a DispatchTimer. This will run your method on the GUI thread. It is the WPF direct equivalent of the Win32 SetTimer/WM_TIMER facility. For example, to call UpdateElapsedTime perioidically:

System.Windows.Threading.DispatcherTimer updateTimer;

updateTimer = new System.Windows.Threading.DispatcherTimer(System.Windows.Threading.DispatcherPriority.Background);

updateTimer.Stop();

updateTimer.Tick += new EventHandler( (sourceObject, args) => { UpdateElapsedTime(); });

Q: How do I provide a default binding/value for a dependency property in a custom control:

A: There are two ways, depending on what you need:

1. To default the property to a constant, specify the constant in the property registrations. For example, this property registration sets the default value of a property named referenceTime to DateTime.Now:

public static readonly DependencyProperty Property_ReferenceTime = DependencyProperty.Register("referenceTime", typeof(DateTime), typeof(TimerTextBlock), new UIPropertyMetadata(DateTime.Now));

2. To default the property to a binding expression, run code in the Initialized or Loaded event.

Q: A programmatically-set binding does not appear to work, but the binding expression syntax is correct. The binding works if it is set manually in the XAML. How do I fix this?

A: Manually create the binding by setting fields in the System.Windows.Data.Binding instead. For example, to create a binding equivalent to {Binding RelativeSource=RelativeSource Mode=Self}, Path=elapsedTimeFormatted, Mode=OneWay}, do the following:

var newBinding = new System.Windows.Data.Binding();

newBinding.RelativeSource = new System.Windows.Data.RelativeSource(System.Windows.Data.RelativeSourceMode.Self);

newBinding.Path = new PropertyPath("elapsedTimeFormatted");

newBinding.Mode = System.Windows.Data.BindingMode.OneWay;

SetBinding(TextProperty, newBinding);

Q: How can I determine why a programmatically set binding does not seem to be working?

A: Enable WPF's binding logging by setting the trace level for the binding to High like this:

System.Diagnostics.PresentationTraceSources.SetTraceLevel(newBinding, System.Diagnostics.PresentationTraceLevel.High);

SetBinding(TextProperty, newBinding);

Q: When should code in a custom control attempt to first use the values of properties?

A: In the Loaded event.

Q: My animated ellipse gets slightly bigger when I animate it. Why?

A: The layout location settings are incorrect. The control is positioned using Margin inside a parent, most likely a grid. To resolve this:

1. Use a Canvas or create rows and columns in the parent grid to position the control absolutely.

2. Set Width and Height on the ellipse to fix it's size. Note that this alone will not resolve the issue.

Q: How do I bind to a property of a property?

A: Use the syntax "parent.child". For example, if the DataContext has a property named "address" which has a public property "city", use the binding expression {Binding Path=address.city} to bind to the city property of address. This is supported for multiple parents. HOWEVER, note that if the parent or any component along the path to the child becomes NULL, WPF will NOT refresh the binding when the parent or component receives a valid value. You must force this by manually refreshing the parent or the binding itself. The former method is recommended as it will automatically affect all controls using nested properties from that parent. To do the later, call GetBindingExpression with the DependencyProperty constant identifying the bound property on the control, then call UpdateTarget on this to update the target that receives the value from the binding.

Q: How do I use a space character in a StringFormat?

A: You must begin the format string with {} to permit spaces. For example, to display a DateTime as <time> <date> with a space between <time> and <date>, use a binding string like this: Text="{Binding Path=runStartTime, StringFormat={}{0:t} {0:M}}"

Q: My window looks fine in the VS 2010 designer, but is way too big at runtime. Why?

A: Set the window's SizeToContent property to "WidthAndHeight".

Q: In XAML, how do I refer to DateTime.MinValue?

A: Use the string "{x:Static sys:DateTime.MinValue}". For example, a DataTrigger that fires when a property is equal to DateTime.MinValue looks like this:

<DataTrigger Binding="{Binding Path=programEndTime}" Value="{x:Static sys:DateTime.MinValue}">

...data trigger stuff...

Q: In XAML, how do I refer to the value of an enum?

A: Use the x:Static markup extension. For example, to use an enum value for comparison in a DataTrigger, first import the namespace where the enum is defined:

xmlns:AutomationProgramDesignerView="clr-namespace:Cybernet.Vsil.UI.AutomationProgramDesigner.View;assembly=AutomationProgramDesigner"

Then use the following syntax to refer to the enum value Initializing in the ProgramRunState enumeration located in AutomationProgramDesignerView:

<DataTrigger Binding="{Binding Path=currentProgramState}" Value="{x:Static Member=AutomationProgramDesignerView:ProgramRunState.Initializing}">

Q: How do I specify a non-string for IValueConverter's ConverterParameter?

A: You must use a different syntax to specify the Binding parameters as individual elements instead of packged into a string. For example, say you have a TextBlock that you would like to be invisible (Collapsed) if the property isConnected is true. You have an IValueConverter implementation named BoolToVisibleConverter that converts bool->Visibility as true->Visible and false->collapsed, but in this case you want it to return true->Collapsed and false->Visible. You want to use the same converter and simply change it's behavior via a parameter. Use the following syntax to specify the converter parameter:

Resource declaration (assuming the class BoolToVisibleConverter exists in the commonConverters namespace):

<commonConverters:BoolToVisibleConverter x:Key="BoolToVisibleConverter" />

Window XAML:

<TextBlock>

<TextBlock.Visibility>

<Binding Path="isConnected" Converter="{StaticResource BoolToVisibleConverter}">

<Binding.ConverterParameter>

<sys:Boolean>False</sys:Boolean>

</Binding.ConverterParameter>

</Binding>

</TextBlock.Visibility>

Remote services are currently unavailable.

</TextBlock>

Q: Why are WPF Labels and TextBoxes taller than TextBlocks with corresponding text, and how do I reduce the height?

A: Set the Padding property to 0. Labels have a default Padding of 5, which makes them much taller than they need to be.

Q: I bound the height of a tab control to the Items property using a value converter to get the maximum desired height, but the height calculated is always zero. Why?

A: Move the Height property binding so it appears after all of the TabItems. XAML properties are evaluated in the order encountered. If the Height attribute is set before the TabItem definitions, it will never be recalculated because the Items property is not set equal to something else, so no PropertyChanged notification is ever fired. Logically, it does change as items are added to the collection, but this does not fire the notification needed to force recalculate of the Height binding.

Q: In XAML, I added a reference to a class in this window's namespace in resources, but the Visual Studio Designer keeps reporting Undefined CLR namespace. The 'clr-namespace' URI refers to a namespace '<YourNamespaceHere>' that is not included in the assembly.

A: Add a 32-bit (x86) configuration to this project and do all visual design in that configuration, or use a different designer. The Visual Studio 2010 designer runs as a 32-bit process and cannot load the assemblies produced by a 64-bit project configuration.

Q: The Visual Studio designer does not recognize a new WPF control assembly I added to to my window. I get 5 errors from the XAML parser referencing my new namespace, claiming that it is not found. For example: "The type 'exttoolkit:<Unknown>' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built."

A: Unblock the assembly file in Explorer. This typically occurs when downloading an assembly from the Internet. Internet Explorer will mark the file as originating from the Internet Zone, causing Windows to block access to it due to Windows NET assembly security. The steps to unblock the file are:

    1. Locate the assembly file in Explorer

    2. Right click the file and select properties

    3. At the bottom of the General tab, click the Unblock button.

Q: How do I use the DesignWidth and DesignHeight elements in the Visual Studio 2010 WPF Designer? The designer responds to the settings, but at build time I get "The property 'DesignWidth' does not exist in XML namespace...

A: You must tell the Visual Studio XAML compiler to ignore these elements by using the OpenXML ignore element. Assuming the Blend namespace providing the DesignHeight/DesignWidth elements is imported as d (xmlns:d="http://schemas.microsoft.com/expression/blend/2008"), add the following to to your window/user control XAML to resolve this:

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"

The designer will still recognize and use the d: settings, but the builder will no longer report an error.

Q: How do I set the starting or initial size of a WPF window while allowing it to be resizeable or size to content?

A: Set ResizeMode="CanResize" and the Width and Height properties of the window to the initial size it should be, then add a Window Loaded handler that calls ClearValue(WidthProperty) and ClearValue(HeightProperty).

Q: How do I set the Source URL of a WebBrowser control and wait until it has finished loading the page?

A: Hook the LoadCompleted event before setting Source. If this logic is in an event handler, as is most likely, you must return from the handler for the WebBrowser to handle the load. The following code which seems correct to a Win32 programmer will deadlock in WPF:

webBrowser.LoadCompleted += new LoadCompletedEventHandler((senderObject, args) => loadCompletedEvent.Set()); webBrowser.Source=sourceURI;

Q: When viewing local HTML/SVG using scripts in the WPF WebBrowser control, scripts are blocked and I get the warning "To help protect your security, your web browser has restricted this file from showing active content that could access your computer." I must click Allow Blocked Content for the page to work. How do I programmatically tell WebBrowser to allow this?

A: Disable IE's LOCALMACHINE_LOCKDOWN security feature by calling CoInternetSetFeatureEnabled(INTERNETFEATURELIST.FEATURE_LOCALMACHINE_LOCKDOWN, SET_FEATURE_ON_PROCESS, false) in your constructor. In XPSP2, Microsoft introduced new security features in Internet Explorer that also apply to embedded IE instances. These can be disabled by calling CoInternetSetFeatureEnabled. This corresponds to IE's Allow Active Content setting. This requires a pinvoke call as there is no managed interface. The declarations needed are as follows.

[Flags] private enum CoInternetSetFeatureEnabled_SetFlags { SET_FEATURE_ON_THREAD = 0x00000001, SET_FEATURE_ON_PROCESS = 0x00000002, SET_FEATURE_IN_REGISTRY = 0x00000004, SET_FEATURE_ON_THREAD_LOCALMACHINE = 0x00000008, SET_FEATURE_ON_THREAD_INTRANET = 0x00000010, SET_FEATURE_ON_THREAD_TRUSTED = 0x00000020, SET_FEATURE_ON_THREAD_INTERNET = 0x00000040, SET_FEATURE_ON_THREAD_RESTRICTED = 0x00000080 } private enum INTERNETFEATURELIST { FEATURE_OBJECT_CACHING = 0, FEATURE_ZONE_ELEVATION = 1, FEATURE_MIME_HANDLING = 2, FEATURE_MIME_SNIFFING = 3, FEATURE_WINDOW_RESTRICTIONS = 4, FEATURE_WEBOC_POPUPMANAGEMENT = 5, FEATURE_BEHAVIORS = 6, FEATURE_DISABLE_MK_PROTOCOL = 7, FEATURE_LOCALMACHINE_LOCKDOWN = 8, FEATURE_SECURITYBAND = 9, FEATURE_RESTRICT_ACTIVEXINSTALL = 10, FEATURE_VALIDATE_NAVIGATE_URL = 11, FEATURE_RESTRICT_FILEDOWNLOAD = 12, FEATURE_ADDON_MANAGEMENT = 13, FEATURE_PROTOCOL_LOCKDOWN = 14, FEATURE_HTTP_USERNAME_PASSWORD_DISABLE = 15, FEATURE_SAFE_BINDTOOBJECT = 16, FEATURE_UNC_SAVEDFILECHECK = 17, FEATURE_GET_URL_DOM_FILEPATH_UNENCODED = 18, FEATURE_TABBED_BROWSING = 19, FEATURE_SSLUX = 20, FEATURE_DISABLE_NAVIGATION_SOUNDS = 21, FEATURE_DISABLE_LEGACY_COMPRESSION = 22, FEATURE_FORCE_ADDR_AND_STATUS = 23, FEATURE_XMLHTTP = 24, FEATURE_DISABLE_TELNET_PROTOCOL = 25, FEATURE_FEEDS = 26, FEATURE_BLOCK_INPUT_PROMPTS = 27, FEATURE_ENTRY_COUNT = 28 }; [DllImport("urlmon.dll")] [PreserveSig] [return:MarshalAs(UnmanagedType.Error)] static extern int CoInternetSetFeatureEnabled( INTERNETFEATURELIST FeatureEntry, CoInternetSetFeatureEnabled_SetFlags dwFlags, bool fEnable );

If you need more control such as this, such as to force the zone that the WebBrowser control runs in or get certain security information, you must implement a custom security manager (IInternetSecurityManager), along with IOleClientSite/IActiveScriptSite to install the hook. See http://msdn.microsoft.com/en-us/library/ms537182(v=vs.85) for more information.

Q: Location services do not function in the WebBrowser control. Scripts report window.navigator.geolocation property is null.

A: This is a bug that Microsoft is aware of. There is currently no programmatic workaround. Microsoft suggests you open the site in the full IE browser and select Always Allow at the security prompt. See this msdn blog and this posting acknowledging this as an issue.

Q: How do I force a control to refresh?

A: One way to do this is to reassign the binding. For example:

void ForceRefreshBinding( FrameworkElement targetControl, DependencyProperty propertyToRefresh ) { BindingExpression targetExpression = targetControl.GetBindingExpression(depprop); Binding propertyBinding = targetExpression.ParentBinding; cntrl.SetBinding(targetControl, propertyBinding); }

Q: How do I set a flags enum to multiple flags in XAML?

A: Use commas to separate the values, as in: <ns:SomeControl Flags="FlagA,FlagB" /> Courtesy stackoverflow.

Q: Is there a way to define a table of string resources in XAML, such that Visual Studio will generate a code identifier for each one as it does for controls?

A: No. Identifier generation only works for window/user control children - children of partial classes generated by the designer. To accomplish this, add a RESX file to your project instead and define the strings in it. For more information, see the bottom of this link.

Q: How do I change the content of a WPF checkbox based on the checkmark?

A: Use a trigger, specified via style. However, make sure that the control does NOT specify a value for Content, or the Content will never be changed regardless of the trigger. Instead, set the initial value using a Setter inside the Style block. For example, the following works:

<CheckBox Name="CaseSensitiveSetAll" HorizontalAlignment="Right" Margin="0 0 5 0" Width="80"> <CheckBox.Style> <Style TargetType="{x:Type CheckBox}"> <Setter Property="Content" Value="Select All"/> <Style.Triggers> <Trigger Property="IsChecked" Value="False"> <Setter Property="Content" Value="Select All" /> </Trigger> <Trigger Property="IsChecked" Value="True"> <Setter Property="Content" Value="Unselect All" /> </Trigger> </Style.Triggers> </Style> </CheckBox.Style> </CheckBox>

But if you added a Content="Select All" attribute to the Checkbox element, it would not. Source is this MSDN posting.

Q: How do I bind a ComboBox to an array of COM objects?

A: This is non-obvious because all NET COM objects are descended from System.ComObject. This is the type that WPF searches for properties, but of course it doesn't find any. This solution assumes that the COM objects are all of the same type and that the project has a reference to an interop DLL for this type. To fix this problem:

1. Add a namespace for the Interop DLL to the XAML. For example, for the interop DLL VisionCom whose namespace is also named VisionCom, add the following namespace declaration to the XAML:

xmlns:XamlVisionCom="clr-namespace:VisionCom;assembly=VisionCom"

2. Bind the ComboBox's ItemsSource to the collection of COM objects.

3. Create a DataItemTemplate for the ComboBox.

4. In the DataItemTemplate, bind the control you wish to use using a special XAML syntax where you specify the type to cast the object to, then the property of the type to use. This syntax is (namespace:interface.property), used after the equals sign in the standard Binding Path= statement, as in:

<ComboBox ItemsSource="{Binding Path=updateConfiguration.strategyDataItems}" > <ComboBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Path=(XamlVisionCom:IATIVisionDataItemInterface.FullDataItemName)}"/> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox>

Reference this MSDN posting by a Microsoft employee.

Q: How do I specify the ItemsSource for a DataGridComboBoxColumn?

A: Set it via the EditingElementStyle property of the element. Using ElementStyle will not work. For example:

<DataGridComboBoxColumn Header="Data Item" MinWidth="150"> <DataGridComboBoxColumn.EditingElementStyle> <Style TargetType="ComboBox"> <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=updateConfiguration.strategyDataItems}"/> <Setter Property="ToolTipService.ToolTip" Value="The VISION strategy data item whose address will be set equal to the address of the symbol specified to the right" /> <Setter Property="ComboBox.ItemTemplate"> <Setter.Value> <DataTemplate> <TextBlock Text="{Binding Path=(XamlVisionCom:IATIVisionDataItemInterface.FullDataItemName)}"/> </DataTemplate> </Setter.Value> </Setter> </Style> </DataGridComboBoxColumn.EditingElementStyle> </DataGridComboBoxColumn>

Q: How do I display a drop shadow on a WPF window whose style is None?

A: There are two ways to to do this. To get Windows to drop the drop-shadow according to display settings, the best way to do this, the workaround is to configure the WPF window to be resizeable, but set the Min=Max, so it can't actually be resized. For example:

<Window x:Class="Duo.Gui.AuthenticationWizard"

...

Height="360" Width="625" 360" MinWidth="625" MaxHeight="360" MaxWidth="625"

WindowStyle="None" ResizeMode="CanResize" >

Courtesy this Stackoverflow posting.

The other way to resolve this is to enable AllowTransparency in the parent window and manually draw a drop-shadow. This is not recommended because it will not fit with different OS visual themes, but can accomplish the effect.

Q: How do I programatically enable WPF tracing?

A: Do the following:

1. Create a System.Diagnostics.TextWriteListener.

2. Call System.Diagnostics.PresentationTraceSources.Refresh().

3. Attach the listener to each source in System.Diagnostics.PresentationTraceSources and set their Switch.Level to All.

Courtesy this msdn blog link.

Q: How to enable Tracing in WCF under mstest

A: Add a config file (app.config) to your WCF project and put these settings in it: https://msdn.microsoft.com/en-us/library/ty48b824(v=vs.110).aspx

The global mstest config file may also need some settings added as per: http://blogs.msdn.com/b/aseemb/archive/2013/01/25/how-to-enable-mstest-logs.aspx

Q: In WPF, how do I use a string resource?

A: This is easy but requires a few steps:

1. Create a RESX file if needed, then determine the namespace and name of the resource class. For example, all projects default to a namespace of [DefaultNamespace].Properties with a class of Resources.

2. In the XAML Window element, add a namespace declaration for this namespace. For example:

xmlns:resx="clr-namespace:Duo.Properties"

3. To use a resource string, use an x:Static referencing the named resource within the resource class in this namespace. For example:

<Button ToolTip="{x:Static resx:Resources.Tooltip_Push}" />

Q: In WPF, when I try to use a string resource, I get an exception when my window is created: System.Windows.Markup.XamlParseException: Provide value on 'System.Windows.Markup.StaticExtension' threw an exception

A: In Visual Studio, goto the RESX file and change the Access Modifier to Public.