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

时间:2015-08-12 15:26:31

标签: c# wpf xaml combobox multibinding

我正在尝试根据ComboBox中的特定属性更改ViewModel中所有项目内容的文字。我创建了一个DataTemplateBinding的值为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。我尝试用SelectedValue替换Text,但这也不起作用。有没有办法将此转换应用于下拉列表中的所有值(同样,只更改显示的值,而不是基础数据)?

更新 - 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();
   }
}

3 个答案:

答案 0 :(得分:0)

您可以将MultiBinding用作SomeProperty

,而不是使用ConverterParameter
<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;
   ...

答案 1 :(得分:0)

问题实际上是你的itemTemplate应用于组合框中的 ALL!项目,其转换器实际处理当前所选项目,而某些属性导致所有项目中的值相等。

此时的方法不是问题。您只需将当前文本的值绑定到viewmodel 而不是选定的值。

这会将viewmodel中的两个值组合到文本框中显示的结果中,而不进行任何递归更新。

答案 2 :(得分:0)

最后想出了如何做到这一点。下面是将转换器应用于下拉列表中所有元素的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>
相关问题