【问题标题】:Apply conversion to all elements in a ComboBox drop down menu将转换应用于 ComboBox 下拉菜单中的所有元素
【发布时间】:2015-11-05 07:34:48
【问题描述】:

我正在尝试根据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();
   }
}

【问题讨论】:

  • 请提供转换器和受影响的视图模型代码
  • @MABVT - 转换器非常基本,只接受值并返回新转换的文本值。 ViewModel 有一组频道ChannelValues,选中频道ChannelSomeProperty

标签: c# wpf xaml combobox multibinding


【解决方案1】:

您可以将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;
   ...

【讨论】:

  • PropertyInChannelValue 会是什么?
  • 我不知道,因为我不知道您在 ChannelValues 中有哪些类型。它们是您自己的自定义类,还是字符串、枚举值等?
  • 用 ViewModel 更新问题。
  • 我得到以下异常A 'Binding' cannot be set on the 'ConverterParameter' property of type 'Binding'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.
【解决方案2】:

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

此时的方法不是问题。您只需要绑定当前文本的值在视图模型中而不是选定的值。

这会将您的视图模型中的两个值组合到文本框中显示的结果中,而无需任何递归更新。

【讨论】:

  • 如果我将其更改为&lt;Binding Path=".Text" RelativeSource="{RelativeSource Self}" /&gt;,它只会递归调用转换器,因为文本正在更改。
  • 然后考虑立即绑定到模型中的值(顺便说一句,这完全消除了转换器的要求,因为转换可以在视图模型中进行......)
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 2021-12-08
    • 1970-01-01
    • 2018-02-08
    • 1970-01-01
    • 2014-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    相关资源
    最近更新 更多