我有以下XML:
<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 :(得分:1)
除非有技术原因导致无法实现,否则我建议您绑定到ViewModel而不是绑定到XAML树中的元素。使用ViewModel,您可以将itemList.SelectedItem绑定到ViewModel上的属性(例如,将其命名为CurrentItem)。此外,将Image的Source绑定到另一个ViewModel属性(可能名为StatusImageSource)。然后,当用户更改itemList中的选定值时,您可以检查CurrentItem.Set中标签值的相等性,并相应地更新StatusImageSource值。
答案 1 :(得分: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。