2012-12-08 61 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