当Item不是ItemsSource集合的一部分时如何设置ComboBox的SelectedItem? [英] How to set SelectedItem of a ComboBox when item is not part of the ItemsSource collection?

查看:801
本文介绍了当Item不是ItemsSource集合的一部分时如何设置ComboBox的SelectedItem?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下情况:

 < ComboBox ItemsSource ={Binding Path = Names}
SelectedItem = {Binding Path = Name,UpdateSourceTrigger = PropertyChanged}>
< / ComboBox>

Names是一个字符串集合,可能会通过ViewModel中的代码更改。例如,名称可以设置为男性名字(约翰,保罗,乔治)或女性名字(玛丽,简,凯伦)。



让我们假设男性集合是活跃的并且用户选择John使其成为SelectedItem。现在集合更改为女性名称。默认情况下,SelectedItem将被设置为Null,John将不再显示。



我想实现的是John仍然可以看作SelectedItem,虽然它不再在集合中了。但是因为它不是集合的一部分,我想将SelectedItem的颜色更改为红色。



我已经玩过IsEditable属性,但没有就像ComboBox的外观改变一样。



我试图使用不同的模板和样式(例如Template,ItemTemplate,ItemContainerStyle),但没有找到



是否可以按照我需要的方式设置所提供的ComboBox的样式,或者我必须创建自己的用户控件吗?



编辑:
我找到了一个我可以住的解决方案。

 < ComboBox IsEditable =TrueIsReadOnly =True
ItemsSource ={Binding Path = Names}
Text ={Binding Path = Name}>
< ComboBox.Style>
< Style TargetType ={x:Type ComboBox}>
< Style.Triggers>
< DataTrigger Binding ={Binding Path = IsNameInCollection}Value =False>
< Setter Property =ForegroundValue =Red/>
< / DataTrigger>
< / Style.Triggers>
< / Style>
< /ComboBox.Style>
< ComboBox.ItemContainerStyle>
< Style TargetType ={x:Type ComboBoxItem}>
< Setter Property =ForegroundValue =Black/>
< / Style>
< /ComboBox.ItemContainerStyle>
< / ComboBox>

在ViewModel中,我确保 Name 收集更改。

解决方案将会更新布尔属性 IsNameInCollection div>

注意:这不是一个真正的,有效的答案/解决方案,但只是一些你可能觉得值得考虑的想法:



首先,如果集合发生变化(通过将其替换为新集合或清除并重新填充它), SelectedItem 将始终更改为null。所以,当你绑定到 Name 属性的某个对象,你能阻止该属性被覆盖内部为null吗?这样,在ComboBox中的值可能不会改变(也许你还需要TwoWayBinding Name 来使值保持不变;甚至发出一个更改事件,但这取决于一些测试)。



其次,渲染需要改变,所以最简单的方法是使用 ItemTemplate code> IValueConverter 实现来转换具有不同颜色/样式的特殊条目的信息。但是这样做的缺点是, ItemTemplate 通常用于每个条目,包括当前选择的条目。



一种处理方法是使用 ItemTemplateSelector ,如下所述: http://www.wpftutorial.net/datatemplates.html (如何使用DataTemplateSelector根据数据切换模板部分)



另一种方式是使用容器而不是纯字符串。该容器还将保存一个布尔值以指示不同的呈现。该布尔值可以在 ItemTemplate 中使用。但是在这种情况下,你需要包装所有的字符串值。



第三,如果选择的值仍然是旧的值不在当前列表,然后用户选择另一个值。一个逻辑将是旧的值刚好消失,但是然后用户不能选择它。如果它在列表中仍然可用,那么您必须以某种方式将其添加到当前值的列表,但标记它是一个特殊值。在这两种情况下,您还需要一个逻辑,以便稍后检查是否根据当前可用列表选择了无效的值。



我希望这有助于找到工作


Following scenario:

<ComboBox ItemsSource="{Binding Path=Names}"
          SelectedItem="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}">
</ComboBox>

Names is a string collection which might change through code in the ViewModel. For example Names could be set to either male names (John, Paul, George) or female names (Mary, Jane, Karen).

Let's assume the male collection is active and the user selects "John" making it the SelectedItem. Now the collection changes to female names. By default the SelectedItem will be set to Null and John will not be displayed anymore. Instead an empty string will be displayed.

What I would like to achieve is that "John" is still visible as SelectedItem although it is not in the collection anymore. However as it is not part of the collection I would like to change the color of the SelectedItem to red.

I have played around with the IsEditable property, but didn't like the changing appearance of the ComboBox. The user should not be able to enter text manually anyway.

I tried to use different templates and styles (e.g. Template, ItemTemplate, ItemContainerStyle), but didn't find a way to use it to my favour.

Is it possible to style the provided ComboBox the way I need it or do I have to create my own user control?

EDIT: I have found a solution I can live with.

<ComboBox IsEditable="True" IsReadOnly="True"
          ItemsSource="{Binding Path=Names}"
          Text="{Binding Path=Name}">
  <ComboBox.Style>
    <Style TargetType="{x:Type ComboBox}">
      <Style.Triggers>
        <DataTrigger Binding="{Binding Path=IsNameInCollection}" Value="False">
          <Setter Property="Foreground" Value="Red"/>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </ComboBox.Style>
  <ComboBox.ItemContainerStyle>
    <Style TargetType="{x:Type ComboBoxItem}">
      <Setter Property="Foreground" Value="Black"/>
    </Style>
  </ComboBox.ItemContainerStyle>
</ComboBox>

In the ViewModel I make sure that the Name property does not change when the Names collection changes. The boolean property IsNameInCollection will be updated when the Name property or the collection changes.

解决方案

Note: this no a real, working answer / solution, but just some thoughts you might find worth to consider:

First, the SelectedItem will always change to null if the collection changes (either by replacing it with a new collection or clearing and refilling it). So as you are binding to Name property of some object, can you prevent that property from being overridden with null there internally? That way the value might not change in the ComboBox (maybe you also need TwoWayBinding for Name to make the value stick; or even firing a change event, but that depends on some testing).

Second, the rendering needs to change, so the easiest way would be to use the ItemTemplate and a custom IValueConverter implementation to convert the information of the special entry with different color / style. But the downside of this is, that the ItemTemplate will normally be used for every entry, including the current selected.

One way to deal with this is to use an ItemTemplateSelector like described here: http://www.wpftutorial.net/datatemplates.html (section "How to use a DataTemplateSelector to switch the Template depending on the data")

Another way would be to use a container instead of plain string. That container would also hold a boolean value to indicte a different rendering. That boolean value could be used in the ItemTemplate. But in this scenario you need to wrap all string values.

Third, how should the ComboBox react if the selected value is still the old value that is not in the current list, and then the user selects another value. One logic would be that the old value just disappears, but then the user cannot select it back. If it should be still available in the list, then you must somehow add it to the list of current values, but mark it that it is a special value. In both cases you also need a logic that detects later if a value was chosen that is not valid according to the current available list.

I hope this helps to find a working solution.

这篇关于当Item不是ItemsSource集合的一部分时如何设置ComboBox的SelectedItem?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆