a converter returning ContentPresenter - strange result
I'm really confused with ContentPresenter.
I want to build a converter having on input a resource name and returning a new ContentPresenter containing a new instance of that resource. Seems to be obvious and straightforward, but when I apply it in xaml the content will... jump between places where it is used:
The converter:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return null;
var key = value.ToString();
var control = new ContentPresenter();
control.SetResourceReference(ContentPresenter.ContentProperty, key);
return control;
}
It expects a string containing a name of a resource and returns new ContentPresenter with this resource.
In xaml I use it twice:
<Window.Resources>
<Button x:Key="TestButton" Height="20" Width="30" Content="test"/>
<local:SelectReso开发者_如何转开发urceConverter x:Key="SelectResourceConverter" />
</Window.Resources>
<StackPanel>
<Button Height="100" Content="{Binding Resource, Converter={StaticResource SelectResourceConverter}}" />
<Button Height="100" Content="{Binding Resource, Converter={StaticResource SelectResourceConverter}}" />
</StackPanel>
'Resource' property is defined in the code behind:
public Window1()
{
InitializeComponent();
DataContext = this;
}
public string Resource
{
get { return "TestButton"; }
}
Changing ContentPresenter to ContentControl gives me an exception in the converter that the element is already in a visual tree. Which gives me a clue, that SetResourceReference() returns twice the same instance, but I don'y know how to change the code to help.
Your help will be very appreciated.
This really sounds like a scenario where you want to use a DataTemplate instead.
In the converter set the ContentTemplateProperty instead:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return null;
var key = value.ToString();
var control = new ContentPresenter();
control.SetResourceReference(ContentPresenter.ContentTemplateProperty, key);
return control;
}
In XAML, define a DataTemplate "TestButton":
<Window.Resources>
<DataTemplate x:Key="TestButton">
<Button Height="20" Width="30" Content="test"/>
</DataTemplate>
<local:SelectResourceConverter x:Key="SelectResourceConverter" />
</Window.Resources>
<StackPanel>
<Button Height="100" Content="{Binding Resource, Converter={StaticResource SelectResourceConverter}}" />
<Button Height="100" Content="{Binding Resource, Converter={StaticResource SelectResourceConverter}}" />
</StackPanel>
If i'm not forgetting something, this should be enough. Through the DataTemplate
you'll get a new instance of your Button for every ContentPresenter
the Converter creates.
You do realize though you'd get a Button in a Button with your code? Not sure why you'd want that...
精彩评论