如何绑定两个DynamicResources?

时间:2011-03-09 17:28:54

标签: wpf data-binding

我试图将元素的值绑定到第一个资源(如果存在),否则绑定另一个资源。

换句话说,如果资源看起来像

<s:String x:Key="first">Hello<s:String> <s:String x:Key="second">World<s:String>

我元素的值将保持Hello

但如果资源只有

<s:String x:Key="second">World<s:String>

该值将为World

我尝试了许多解决方案,但似乎都没有效果或足够优雅。

我希望我能写

<MyElement> <MyElement.Value><MultiBinding Converter=...><DynamicResource Key=First/><DynamicResource Key=Second/> ...

转换器负责查找第一个非空值。

但是,WPF不允许混合DynamicResource和MultiBinding

你有解决方案吗?

1 个答案:

答案 0 :(得分:0)

编辑1:我可能已经把你的问题读得太快了......你绑定了动态资源......而不是类属性......所以下面的解决方案可能不是你想要的。但是我现在就把它留下来,以防它帮你提出解决方案。

编辑2:我在Visual Studio 2010 SP1中尝试了以下代码,它在设计器中的工作方式(注释/取消注释资源'first')。但它无法成功构建......我觉得很奇怪:

<TextBlock>
    <TextBlock.Resources>
        <!--<s:String x:Key="first">Hello</s:String>-->
        <s:String x:Key="second">World</s:String>
        <l:NullItemConverter x:Key="NullItemConverter" />
    </TextBlock.Resources>
    <TextBlock.Text>
        <MultiBinding Converter="{StaticResource NullItemConverter}">
            <Binding Source="{DynamicResource first}" />
            <Binding Source="{DynamicResource second}"/>
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

public class NullItemConverter : IMultiValueConverter
{
    object IMultiValueConverter.Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return values[0] ?? values[1];
    }

    object[] IMultiValueConverter.ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

原始答案(不能回答您的问题,但根据您的具体情况可能有所帮助):

假设您的两个属性属于同一个类,您是否可以创建第三个属性,巧妙地输出正确的值并绑定到该属性:

public class MyObject : INotifyPropertyChanged
{
    private string property1;
    public string Property1
    {
        get { return this.property1; }
        set
        {
            if (this.property1 != value)
            {
                this.property1 = value;
                NotifyPropertyChanged("Property1");
                NotifyPropertyChanged("PropertyForBinding");
            }
        }
    }

    private string property2;
    public string Property2
    {
        get { return this.property2; }
        set
        {
            if (this.property2 != value)
            {
                this.property2 = value;
                NotifyPropertyChanged("Property2");
                NotifyPropertyChanged("PropertyForBinding");
            }
        }
    }

    public string PropertyForBinding
    {
        get
        {
            return this.Property1 ?? this.Property2;
        }
    }

    public MyObject() { }

    #region -- INotifyPropertyChanged Contract --

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    #endregion INotifyPropertyChanged Contract
}