2012-12-08 33 views
0

我有下面的XML:制作Image.Source取决于文本框的比较和标签值

<Items> 
    <Item> 
    <Name>Item One</Name> 
    <MyValue>42</MyValue> 
    </Item> 
</Items> 

和XAML:

<DockPanel> 
    <DockPanel.Resources> 
     <XmlDataProvider x:Key="ItemsXml" XPath="Items/Item" 
      Source="Resources/Items.xml"/> 
    </DockPanel.Resources> 

    <ListBox 
     ItemsSource="{Binding Source={StaticResource ItemsXml}}" 
     DisplayMemberPath="Name" Name="itemList"/> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="20"/> 
      <ColumnDefinition Width="50"/> 
      <ColumnDefinition Width="*"/> 
     </Grid.ColumnDefinitions> 
     <Grid.Resources> 
      <Style x:Key="ValueFormat" TargetType="Label"> 
       <Setter Property="ContentStringFormat" Value="{}/{0,3}"/> 
      </Style> 
     </Grid.Resources> 

     <Image Source="Icons/ConditionFalse.png" Grid.Column="0"/> 

     <TextBox Name="myTextBox" VerticalAlignment="Center" Grid.Column="1"/> 

     <Label 
      Name="myLabel" 
      DataContext="{Binding SelectedItem, ElementName=itemList}" 
      Style="{StaticResource ValueFormat}" 
      VerticalAlignment="Center" 
      Content="{Binding XPath=MyValue}" 
      Grid.Column="2"/> 
    </Grid> 
</DockPanel> 

我要让Image.Source取决于TextBox.Text是条件等于参考值Label *。引用值是对XML文件的绑定,因此使用它作为比较的基础也很好。 TextBox将绑定到一个尚不存在的属性,以便作为选项提供。

* Label当前使用ContentStringFormat来更改其值。如果这是有问题的,它可以摆脱。

我可以使用a DataTrigger直接绑定到代表这种情况的属性,但感觉像是黑客,我宁愿避免这种情况。我试图设置一个MultiDataTrigger如下所示,但首先我无法得到Label的工作条件(它的确适用于TextBox),其次在我的情况下,常数值不好。当条件评估为false时,它也没有“else”子句或默认值,但如果可以首先进行检查,我希望这将是一个非问题。

<Image Grid.Column="0"> 
    <Image.Style> 
     <Style TargetType="{x:Type Image}"> 
      <Style.Triggers> 
       <MultiDataTrigger> 
        <MultiDataTrigger.Conditions> 
         <Condition Value="/ 42" 
          Binding="{Binding Text, ElementName=myTextBox}"/> 
         <Condition Value="/ 42" 
          Binding="{Binding Content, ElementName=myLabel}"/> 
        </MultiDataTrigger.Conditions> 
        <Setter Property="Source" Value="Icons/ConditionTrue.png"/> 
       </MultiDataTrigger> 
      </Style.Triggers> 
     </Style> 
    </Image.Style> 
</Image> 
+0

转换器或MultiValueConverter怎么样? – Harry

回答

0

哈利的评论让我走向了正确的方向。

XAML:

<Grid.Resources> 
    <local:MyImageConverter x:Key="MyImageConverter"/> 
</Grid.Resources> 

<Image Grid.Column="0" Grid.Row="0"> 
    <Image.Style> 
     <Style TargetType="{x:Type Image}"> 
      <Setter Property="Source" Value="Icons/ConditionFalse.png"/> 
      <Style.Triggers> 
       <DataTrigger Value="True"> 
        <DataTrigger.Binding> 
         <MultiBinding 
          Converter="{StaticResource MyImageConverter}"> 
          <Binding ElementName="myTextBox" Path="Text"/> 
          <Binding ElementName="myLabel" Path="Content"/> 
         </MultiBinding> 
        </DataTrigger.Binding> 
        <Setter Property="Source" Value="Icons/ConditionTrue.png"/> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </Image.Style> 
</Image> 

C#

public class MyImageConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, 
     object parameter, System.Globalization.CultureInfo culture) 
    { 
     System.Xml.XmlElement labelValue = values[1] as System.Xml.XmlElement; 
     if (labelValue != null) 
     { 
      return ((string)values[0]) == labelValue.InnerText; 
     } 
     return false; 
    } 

    public object[] ConvertBack(object value, Type[] targetType, 
     object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotSupportedException(); 
    } 
} 

这很快变得非常凌乱。我现在使用这个,但是随着时间的推移,我会按照Whyaduck的回答将它重新加入ViewModel。

1

除非有就是为什么它是不可能的一个技术原因,我建议您绑定到一个ViewModel,而不是结合在XAML树中的元素。使用ViewModel,您可以将itemList.SelectedItem绑定到ViewModel上的属性(例如,将其称为CurrentItem)。另外,将图像的源代码绑定到另一个ViewModel属性(可能名为StatusImageSource)。然后,当用户更改itemList中的选定值时,可以检查与CurrentItem.Set中标签值的相等性,并适当地更新StatusImageSource值。

+0

我对此表示赞赏,因为这是一种很好的做法,但我不会接受它,因为所述的问题存在解决方案。 – mkjeldsen