繁体   English   中英

如何将不同的属性绑定到ComboBox的SelectedItem和SelectedIValue?

[英]How to bind different properties to SelectedItem and SelectedIValue of ComboBox?

我有一个线程,它每秒更新一次当前的Mode属性。 我还希望有一个选项能够在datagrid的同一单元格内设置模式。 因此,在编辑模式下,我只是显示该模式。 在编辑模式下,我显示了一个填充的ComboBox 现在,

  • 为了能够在ComboBox显示所选项目,当我进入编辑模式时,我将SelectedItem绑定到Mode
  • 为了能够将更改返回到ViewModel,我将SelectedValue绑定到其他属性。 (我需要绑定到其他属性,因为“模式”每秒更新一次,并且会覆盖所选值)。

问题是,尽管SelectedItemMode=OneTime绑定,但它仍会触发SelectedValue属性。 我希望仅当用户选择一个值时才触发SelectedValue

我希望很清楚我要做什么。 那么,我该如何实现呢? 欢迎使用其他方法(即使我需要使用其他控件)。

<DataGridTemplateColumn Header="Mode">
  <DataGridTemplateColumn.CellTemplate>
      <DataTemplate>
          <TextBlock Text="{Binding Mode}"/>
      </DataTemplate>
  </DataGridTemplateColumn.CellTemplate>
  <DataGridTemplateColumn.CellEditingTemplate>
     <DataTemplate>
        <ComboBox ItemsSource="{Binding Source={StaticResource Modes}}"
                  SelectedItem="{Binding Mode, Mode=OneTime}"
                  SelectedValue="{Binding ModeToSet, Mode=OneWayToSource}" 
         />
     </DataTemplate>
  </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

由于组合框的工作方式以及Mode在后台不断变化,因此无法实现需要做的前提。

为什么?

问题是,尽管SelectedItem与Mode = OneTime绑定,但它仍会触发SelectedValue属性。

正如它应该。 OneTime按该文档( BindingMode枚举 )规定:

在应用程序启动或数据上下文更改时更新绑定目标。

根据您的设计,数据上下文始终每秒更改一次。 如果深入阅读说明,则说明

如果您使用的数据适合使用当前状态的快照或数据是真正静态的,则这种类型的绑定是合适的。...这本质上是OneWay绑定的一种更简单的形式...

如果有人OneWay绑定

当绑定源(源)更改时,更新绑定目标(target)属性。如果要绑定的控件是隐式只读的,则这种类型的绑定是合适的。

组合框的最终目的是改变双方SelectedItem ,并获得价值掉SelectedItemSelectedValue

我希望仅当用户选择一个值时才触发SelectedValue。

问题并没有超出控制范围,而是即将出现的问题。

创建一个测试项目,组合框将按照您指定的方式运行,仅当用户选择一个值时才触发所选值。 组合框仅在做出选择或外部值改变了一个值从而改变了另一个时才设置SelectedX属性。

由于Mode不断变化,因此会将更改推入选择范围,反之亦然。

修复建议

我建议您为mode拍摄快照并将其放入ModeOnEdit变量并进行绑定。 当用户做出选择时,捕获事件并更改实际Mode


测试项目

绑定到您自己的数据源后,我的就是Ships。 Ships是一个列表,该对象的属性为Name 船对象上的ToString返回Name

结果是,有两个文本框显示所选项目/值的状态。 用于设置所选值和组合框本身的按钮。

在此处输入图片说明

<Label Grid.Row="1" Grid.Column="1">SelectedItem</Label>
<TextBlock Grid.Row="1" Grid.Column="2" Text="{Binding SelectedItem, ElementName=cbMain}"/>
<Label Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2">SelectedValue</Label>
<TextBlock Grid.Row="3" Grid.Column="2" Text="{Binding SelectedValue, ElementName=cbMain}"/>
<Button Grid.Row="5" Grid.Column="1" Click="ChangeSelectedValue">Set Selected Value</Button>
<ComboBox Name="cbMain"
            Grid.Row="5"
            Grid.Column="2"
            ItemsSource="{Binding Ships}"
            SelectedValuePath="Name"/>

-后面的代码

private void ChangeSelectedValue(object sender, RoutedEventArgs e)
{
    cbMain.SelectedValue = "Pacific Silver";
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM