我正试图基于ViewModel
中的特定属性,仅更改ComboBox
中所有项的内容的文本。我已经创建了一个DataTemplate
,其中Binding
值为SelectedValue
,并且我想要基于SomeProperty
:进行转换的特定属性
<ComboBox ItemsSource="{Binding Path=ChannelValues}"
SelectedValue="{Binding Path=Channel, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource ResourceKey=ChannelNumConverter}">
<Binding Path="SelectedValue"
RelativeSource="{RelativeSource AncestorType={x:Type ComboBox}}" />
<Binding Path="DataContext.SomeProperty"
ElementName="DataContextView" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
这似乎是有效的,期望下拉列表中的所有值都更改为转换后的SelectedValue
。我试过用Text
替换SelectedValue
,但也不起作用。是否有方法将此转换应用于下拉列表中的所有值(同样,仅更改显示的值,而不更改基础数据(?
更新-ViewModel
// Populate somewhere with values
private ObservableCollection<ushort> mChannelValues = new ObservableCollection<ushort>();
public ObservableCollection<ushort> ChannelValues
{
get
{
return mChannelValues;
}
}
private ushort mChannelNum;
public ushort Channel
{
get
{
return mChannelNum;
}
set
{
if (mChannelNum != value)
{
mChannelNum = value;
OnPropertyChanged(new PropertyChangedEventArgs("Channel"));
}
}
}
private ushort mSomeProperty;
public ushort SomeProperty
{
get
{
return mSomeProperty;
}
set
{
if (mSomeProperty!= value)
{
mSomeProperty= value;
OnPropertyChanged(new PropertyChangedEventArgs("SomeProperty"));
}
}
}
更新2-简单转换器
public object Convert(
object[] values,
Type targetType,
object parameter,
CultureInfo culture)
{
if (targetType != typeof(string))
throw new InvalidOperationException("The target must be a string");
if ((values[0] != null) && (!(values[0] is ushort)))
throw new InvalidOperationException("The channel must be an short");
if ((values[1] != null) && (!(values[1] is ushort)))
throw new InvalidOperationException("The some property must be a ushort");
ushort ushort_val = ushort.Parse((string)values[0]);
ushort ushort_some_property = ushort.Parse((string)values[1]);
switch (ushort_some_property)
{
case 0:
return (ushort_val + 1).ToString();
case 1:
return (ushort_val + 7).ToString();
case 2:
return (ushort_val + 2).ToString();
default:
return ushort_val.ToString();
}
}
您可以将SomeProperty
用作ConverterParameter
,而不是使用MultiBinding
<TextBlock Text="{Binding Converter={StaticResource ResourceKey=ChannelNumConverter}, ConverterParameter={Binding SomeProperty}}"/>
转换器内:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var someProperty = parameter as SomeType;
...
问题实际上是您的itemTemplate应用于ALL组合框中的项,其转换器实际处理当前选定的项和导致所有项的值相等的someproperty。
目前的做法不是问题所在。您只需要在视图模型中绑定当前文本的值,而不是选定的值。
这将把视图模型中的两个值合并到文本框中显示的结果中,而不需要任何递归更新。
终于找到了如何做到这一点。下面是将转换器应用于下拉列表中所有元素的xaml:
<ComboBox ItemsSource="{Binding Path=ChannelValues}"
SelectedValue="{Binding Path=Channel, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource ResourceKey=ChannelNumConverter}">
<Binding />
<Binding Path="DataContext.SomeProperty"
RelativeSource="{RelativeSource Mode=FindAncestor,
AncestorType=local:DataContextView}" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>