如何给ComboBox的SelectedItem和SelectedIValue绑定不同的属性?
How to bind different properties to SelectedItem and SelectedIValue of ComboBox?
我有一个线程每秒更新当前 Mode
属性。我还想要一个能够在数据网格中的同一单元格内设置模式的选项。所以,在 not 编辑模式下,我只显示模式。在编辑模式下,我显示了一个已填充的 ComboBox
。
现在,
- 为了能够在
ComboBox
中显示select编辑的项目,当我进入编辑模式时,我将SelectedItem
绑定到Mode
。
- 为了能够将更改返回到 ViewModel,我将
SelectedValue
绑定到另一个 属性。 (我需要绑定到不同的 属性,因为 'Mode' 每秒更新一次,并且会覆盖 selected 值)。
问题是,尽管 SelectedItem
与 Mode=OneTime
绑定,但它仍然会触发 SelectedValue
属性。我希望 SelectedValue
仅在用户 select 一个值时被触发。
我希望我想做的很清楚。那么,我该如何实现呢?欢迎使用其他方法(即使我需要使用不同的控件)。
<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
在后台不断变化的方式,无法实现需要完成的前提。
为什么?
The problem is that though SelectedItem is bound with Mode=OneTime it
still triggers SelectedValue property.
这是应该的。 OneTime
根据文档 (BindingMode Enumeration) 指出:
"在应用程序启动或数据上下文更改时更新绑定目标。"
根据您的设计,数据上下文总是每秒变化一次。如果进一步阅读说明
"如果您使用的数据适合使用当前状态的快照或数据是真正静态的,那么这种类型的绑定是合适的。...这本质上是一种更简单的形式单向绑定..."
如果有人阅读 OneWay
绑定
"当绑定源 (source) 更改时更新绑定目标 (target) 属性。如果被绑定的控件是隐式只读的,则此类型的绑定是合适的。"
组合框的最终设计目的是同时更改 SelectedItem
并将 SelectedItem
的值变为 SelectedValue
I want the SelectedValue to be triggered only when user select a value.
问题不是失控,而是进来的东西....
创建一个测试项目,组合框按照您指定的方式运行,选定的值仅在用户选择一个值时触发。组合框仅在做出选择 或外部值更改一个 时设置 SelectedX
属性,因此它会更改另一个。
由于 Mode
不断变化,它会将变化推送到选择中,而不是相反。
修复建议
我建议您拍摄模式快照并将其放入 ModeOnEdit
变量并绑定它。当用户做出选择时,捕获事件并更改实际的 Mode
.
测试项目
绑定到您自己的数据源,我的是 Ships。 Ships 是一个列表,其中 Name
作为该对象上的 属性。 ToString
在船对象上 returns Name
.
这是结果,有两个文本框显示所选 item/value 的状态。用于设置所选值和组合框本身的按钮。
<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";
}
我有一个线程每秒更新当前 Mode
属性。我还想要一个能够在数据网格中的同一单元格内设置模式的选项。所以,在 not 编辑模式下,我只显示模式。在编辑模式下,我显示了一个已填充的 ComboBox
。
现在,
- 为了能够在
ComboBox
中显示select编辑的项目,当我进入编辑模式时,我将SelectedItem
绑定到Mode
。 - 为了能够将更改返回到 ViewModel,我将
SelectedValue
绑定到另一个 属性。 (我需要绑定到不同的 属性,因为 'Mode' 每秒更新一次,并且会覆盖 selected 值)。
问题是,尽管 SelectedItem
与 Mode=OneTime
绑定,但它仍然会触发 SelectedValue
属性。我希望 SelectedValue
仅在用户 select 一个值时被触发。
我希望我想做的很清楚。那么,我该如何实现呢?欢迎使用其他方法(即使我需要使用不同的控件)。
<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
在后台不断变化的方式,无法实现需要完成的前提。
为什么?
The problem is that though SelectedItem is bound with Mode=OneTime it still triggers SelectedValue property.
这是应该的。 OneTime
根据文档 (BindingMode Enumeration) 指出:
"在应用程序启动或数据上下文更改时更新绑定目标。"
根据您的设计,数据上下文总是每秒变化一次。如果进一步阅读说明
"如果您使用的数据适合使用当前状态的快照或数据是真正静态的,那么这种类型的绑定是合适的。...这本质上是一种更简单的形式单向绑定..."
如果有人阅读 OneWay
绑定
"当绑定源 (source) 更改时更新绑定目标 (target) 属性。如果被绑定的控件是隐式只读的,则此类型的绑定是合适的。"
组合框的最终设计目的是同时更改 SelectedItem
并将 SelectedItem
的值变为 SelectedValue
I want the SelectedValue to be triggered only when user select a value.
问题不是失控,而是进来的东西....
创建一个测试项目,组合框按照您指定的方式运行,选定的值仅在用户选择一个值时触发。组合框仅在做出选择 或外部值更改一个 时设置 SelectedX
属性,因此它会更改另一个。
由于 Mode
不断变化,它会将变化推送到选择中,而不是相反。
修复建议
我建议您拍摄模式快照并将其放入 ModeOnEdit
变量并绑定它。当用户做出选择时,捕获事件并更改实际的 Mode
.
测试项目
绑定到您自己的数据源,我的是 Ships。 Ships 是一个列表,其中 Name
作为该对象上的 属性。 ToString
在船对象上 returns Name
.
这是结果,有两个文本框显示所选 item/value 的状态。用于设置所选值和组合框本身的按钮。
<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";
}