2011-03-09 22 views
1

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

换句话说,如果资源的样子

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

我的元素的值将举行你好

但如果资源只有

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

的价值将是世界

我已经尝试了一些解决方案,但似乎没有工作或足够优雅。

我希望我能写

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

当转换器需要找到的第一个非空值的照顾。

然而,WPF不允许混合DynamicResource和MultiBinding

你有一个解决方案?

回答

0

编辑1:我可能已经读了你的问题有点太快了......你绑定到动态资源......没有类属性......所以下面的解决方案可能不是你想要的。但是现在我会离开它,以防它帮助您找到解决方案。

编辑2:我在Visual Studio 2010 SP1中尝试了下面的代码,它的工作原理就像它应该在设计器中(注释/取消注释资源'第一')。但它未能成功建立...我觉得奇怪:

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