'How can I refer to a binding converter in another namespace in Silverlight XAML?
Since you apparently can't create a Silverlight DataTemplate in C#, I'm trying to create one in XAML. I have a converter that I need to refer to, that I have defined in C# in another namespace. I've tried doing this:
<UserControl.Resources>
<DataTemplate x:Key="PriceTemplate">
<TextBlock Text="{Binding Price, Converter={Converters:PriceConverter}}" />
</DataTemplate>
</UserControl.Resources>
Where Converters is an xmlns that points to the correct namespace. However, I get a compilation error that says:
Type 'Converters:PriceConverter' is used like a markup extension but does not derive from MarkupExtension.
I tried adding System.Windows.Markup.MarkupExtension as a parent to my converter, but it apparently doesn't exist in Silverlight.
How can I refer to my converter in XAML, without having to rewrite it in XAML?
Solution 1:[1]
You want to make a static resource first, then bind to the converter that is a static resource.
<UserControl.Resources>
<conv:IntConverter x:Key="IntConverter"></conv:IntConverter>
</UserControl.Resources>
<StackPanel>
<TextBlock x:Name="Result" Margin="15" FontSize="20"
HorizontalAlignment="Center" VerticalAlignment="Center"
Text="{Binding Converter={StaticResource IntConverter}}">
</TextBlock>
</StackPanel>
</Window>
So the "conv:" xml namespace was registered at the top of the document like you do with custom controls:
xmlns:conv="clr-namespace:MyFooCompany.Converters"
This example is adapted from the below linked tutorial regarding the same issue for WPF:
http://www.dev102.com/2008/07/17/wpf-binding-converter-best-practices/
Solution 2:[2]
You seem to be confusing Types with Instances. A converter type will exist "in" a namespace however in binding we do not specify a type as the converter. Instead we give the binding an actual instance of that type.
Generally IValueConverter
instances are stateless, hence we can hold a common instance anywhere in a the chain of resource dictionaries available where the instance of a DataTemplate is loaded.
In xaml we can reference another namespace by creating a new alias to cover it. With that in mind your xaml could look something like this:-
<UserControl x:Class="SilverlightApplication1.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SilverlightApplication1"
xmlns:localConverters="clr-namespace:SilverlightApplication1.Converters">
<UserControl.Resources>
<localConverters:PriceConverter x:Key="PriceConverter" />
<DataTemplate x:Key="Test">
<TextBlock Text="{Binding Price, Converter={StaticResource PriceConverter}}" />
</DataTemplate>
</UserControl.Resources>
Solution 3:[3]
<RadioButton GroupName="Group1">
<RadioButton.Template>
<ControlTemplate>
<ToggleButton IsChecked="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}">
<ToggleButton.Content>
<SymbolIcon Symbol="Edit"/>
</ToggleButton.Content>
<ToolTipService.ToolTip>
<ToolTip Content="Sample Tooltip" Placement="Mouse" />
</ToolTipService.ToolTip>
</ToggleButton>
</ControlTemplate>
</RadioButton.Template>
</RadioButton>
Adding to the answer posted by @Rokk.
Solution 4:[4]
In addition to the other answers suggesting creating an instance of the ValueConverter in a resource dictionary, another solution is to implement it via a MarkupExtention:
public class IntToLetterConverter : IMarkupExtension<IValueConverter>, IValueConverter
{
public IValueConverter ProvideValue(IServiceProvider serviceProvider)
=> (IValueConverter)this;
object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
=> ((IMarkupExtension<IValueConverter>)this).ProvideValue(serviceProvider);
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
=> (char)('a' + (int)value);
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
=> (int)((char)value - 'a');
}
With this solution you can directly reference the converter (which is in essence a MarkupExtension) whithout defining a resource.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | AnthonyWJones |
Solution 3 | Madushan Amarasinghe |
Solution 4 | Peter de Leeuw van Weenen |