Add converter to page resources from code behind - wpf

I would like to add a specific instance of a class to the resources of a page then use that class as a converter, so in my page constructor I put:
this.Resources.Add("converterASD", new ASDConverter());
then bind to it like this:
<ListBox ItemsSource="{Binding Converter={StaticResource converterASD}}"/>
but I keep getting this exception:
Provide value on 'System.Windows.Markup.StaticResourceHolder' threw an
exception.
I'm a bit new to WPF, any advice would be appreciated.

We could use more information from the exception.
Two suggestions:
Make sure that you add the resource before the call to InitializeComponent().
Try switching it to a dynamic resource.

You can declare the Converter you would like to use in the resource section of the page like the following example. (I recommend you declare the converter in XAML instead of the code-behind)
Example:
<UserControl x:Class="Views.ConverterExample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="300"
d:DesignWidth="300">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter" />
</UserControl.Resources>
<Grid>
<CheckBox x:Name="VisibilityController" IsThreeState="False" />
<ListBox
Visibility="{Binding ElementName=VisibilityController, Path=IsChecked,Converter={StaticResource BoolToVisibilityConverter}}"
Height="100" Width="100" BorderBrush="Red" BorderThickness="1" />
</Grid>
</UserControl>

Related

Binding to a new IENumerable declared in XAML NOT CodeBehind

The XAML below is incorrect, but it represents what I'm trying to do. I'm fairly new to WPF, but I want to know if something like this doable without instead declaring the instance in the code behind?
<ListBox Name="lbInstalledFonts" VerticalContentAlignment="Center" DisplayMemberPath="Name" ItemsSource="{Binding Source={new System.Drawing.Text.InstalledFontCollection().Familes}}" />
To elaborate, I only need the list of System.Drawing.Text.InstalledFontCollection().Familes for this ListBox. That's it. So I was thinking I could do it entirely through the XAML in a similar way to how you could bind to a DataSource in ASP.NET (through the use of <% and %> in the aspx/ascx files)? Is this at all possible? I did some searching but didn't have much luck.
Yes, it is possible:
<Window x:Class="HelpStackOverflow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:drawing="clr-namespace:System.Drawing.Text;assembly=System.Drawing"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<drawing:InstalledFontCollection x:Key="InstalledFontCollection" />
</Window.Resources>
<Grid>
<ListBox Name="lbInstalledFonts"
VerticalContentAlignment="Center"
DisplayMemberPath="Name"
ItemsSource="{Binding Source={StaticResource InstalledFontCollection}, Path=Families}" />
</Grid>
</Window>

Unable to reference/bind to view template in user control

I have a view template in a user control as below
<UserControl
x:Class="Configuration.Views.viewProfileTemplate"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Background="Azure" Width="233">
<StackPanel Height="300" HorizontalAlignment="Left" Name="stackPanel1" VerticalAlignment="Top" Width="230">
<TextBox Text="{Binding Path=SomeProfileText}" Margin="10" />
<ListBox ItemsSource="{Binding Path=Profiles}" Height="70" Margin="10"/>
<CheckBox Content="CheckBox" Height="16" Name="checkBox1" Width="175" />
</StackPanel>
</Grid>
</UserControl>
The user control is defined as below in the main.xaml window
<Window x:Class="Configuration.TreeUI"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:Configuration.Views"
xmlns:local="clr-namespace:Configuration"
Title="TreeUI" Height="300" Width="450" WindowStyle="ToolWindow">
I atempt to use the template with
<DataTemplate DataType="{x:Type local:ProfileViewModel}">
<Views:viewProfileTemplate/>
</DataTemplate>
But the compiler reports :
Error 1 The type 'Views:viewProfileTemplate' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built.
I again am missing som important point, but what ?
Going to owe someone a big drink .....
There are two potential causes for this:
1) If the data template is in a different assembly than viewProfileTemplate, you need to make the xaml reflect this:
xmlns:views="clr-namespace:Configuration.Views;assembly=ViewAssembly"
Note that this will also require a reference to be added to the project properly to function.
2) If this is a design time error, make sure to build the solution first. The WPF designer in VS often will report errors about missing types until you've built once, then it "works" properly.

In WPF how do I access a WrapPanel from CodeBehind

I have a WrapPanel defined as follows in XAML...
<Page x:Class="SelectImages"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="320" d:DesignWidth="480"
Title="Select Images">
<Grid>
<WrapPanel Name="MyImagePanel" Width="Auto" Height="Auto" Margin="10,50,10,10" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto" Orientation="Horizontal">
</WrapPanel>
</Grid>
</Page>
When I try to use the WrapPanel as below in my Code Behind I get a runtime error "Object reference not set to instance of object".
Private Sub AddImageToPanel(Image As FileSystemInfo)
MyImagePanel.Children.Add(NewPicture(Image))
End Sub
Can anyone tell me what I've done wrong?
I was navigating to this page using ...
Dim SelectImagesPage As New SelectImages(FolderPath, SelectedProductID)
Me.NavigationService.Navigate(SelectImagesPage)
Seems the constructor doesn't automatically initialise the components. Added InitializeComponent() to the constructor on my page and now it all works.

How can I display my user control in the MainWindow?

I'm trying to build a small MVVM test application, but can't really figure how to display my user control in the MainWindow.
My Solution Explorer:
I got a resource dictionary:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:MVVM.ViewModel"
xmlns:vw="clr-namespace:MVVM.View">
<DataTemplate DataType="{x:Type vm:ViewModel}">
<vw:View />
</DataTemplate>
</ResourceDictionary>
I got my view:
<UserControl x:Class="MVVM.View.View"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<DataTemplate x:Key="PersonTemplate">
<StackPanel>
<TextBlock Text="{Binding FirstName}" />
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<ListBox ItemsSource="{Binding Path=Persons}"
ItemTemplate="{StaticResource PersonTemplate}" />
</UserControl>
and My MainWindow
<Window x:Class="MVVM.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:MVVM.ViewModel"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary Source="MainWindowResources.xaml" />
</Window.Resources>
<Grid>
</Grid>
</Window>
The most obvious and easiest way is to add the ContentControl element:
<Grid>
<ContentControl x:Name="mainContentControl" />
</Grid>
And after that set the Content property of this control to your view model, and the corresponding view will be loaded and applied automatically:
this.mainContentControl.Content = new ViewModel.ViewModel();
But I would prefer to use another way without datatemplates:
<Grid>
<vw:View x:Name="mainView"/>
</Grid>
this.mainView.DataContext = new ViewModel.ViewModel();
Build your VS2010 solution, then, go to your MainWindow's XAML.
On the left, there is a toolbar with button "Toolbox"
Open it, it contains all the possible WPF controls you could add to your UI
Your UserControl should appear on top of the list (in a category probably named "MVVM Controls"), just drag&drop it to your UI :)

How to set tooltip for user control (from style file)

I created my control which looks like that
<UserControl BorderBrush="#A9C2DE" HorizontalAlignment="Left" x:Class="WPFDiagramDesignerControl.Components.UcWBSBlock"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="86" Width="151" >
<UserControl.Resources>
<ResourceDictionary Source="Tooltip.xaml"/>
</UserControl.Resources>
<Grid x:Name="MainGrid">
<TextBox Name="txtBox" Style="{StaticResource DefaultStyle}" >
</TextBox>
</Grid>
I also have a file with style for tooltip "Tooltip.xaml"
How can I use this style for entire UserControl?
Usually I did this with that code
<TextBox ToolTip="{StaticResource tooltipname}"/>
But it was easy because file with style was in resource dictionary of control where I placed textbox. However I can't do sth like that
<UserControl BorderBrush="#A9C2DE" HorizontalAlignment="Left" ToolTip="{StaticResource tooltipname"}/>
Because at this point my style isn't in resource dicionary yet.
I was trying to use this syntax
<UserControl.ToolTip> </UserControl.ToolTip>
but I don't konow how should I refer to static resource
Maybe it is lame question but I just don't konow how to do it :)
One option is to just use DynamicResource instead of StaticResource to defer the lookup until runtime and then use the attribute syntax:
<UserControl ... ToolTip="{DynamicResource tooltipname}" ...
You can also write the StaticResourceExtension using element syntax so that you can write it after the Resources section:
<UserControl.Resources>
<ResourceDictionary Source="Tooltip.xaml"/>
</UserControl.Resources>
<UserControl.ToolTip>
<StaticResourceExtension ResourceKey="tooltipname"/>
</UserControl.ToolTip>

Resources