将转换应用于组合框下拉菜单中的所有元素

本文关键字:元素 下拉菜单 转换 应用于 组合 | 更新日期: 2023-09-27 18:07:28

我正试图基于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>