开发者

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...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜