我正在尝试在其SelecteItem
属性上使用带有数据绑定的WPF组合框。当用户选择新选择时,SelectedItem
会更改,但我的模型未正确更新,并且SelectionBoxItem
(组合框中显示的项目)不会更改。
更具体地说,我有以下两个要素:
<ListView Name="lvNodes" ItemsSource="{Binding Path=Nodes}" SelectedItem="{Binding Path=CurrentNode, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
此listview按预期工作。有问题的组合框定义如下
<ComboBox ItemsSource="{Binding Path=CameraViews}" SelectedItem="{Binding Path=CurrentNode.NodeInfo.Camera1, Converter={StaticResource EnsureBlank}, Mode=TwoWay}" Name="comboBoxTopCam" SelectionChanged="comboBoxTopCam_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
因此,当用户从ListView(上面)中选择一个节点时,ComboBox会更新以显示该节点正在使用的摄像头。
现在奇怪的行为。如果用户单击组合框上的新项,我可以使用调试器停止并检查SelecteItem
属性。这始终设置正确,但CurrentNode.NodeInfo.Camera1
属性不会更改,并且“SelectionBox”中显示的字符串不会更改。
然而,它变得更加陌生。如果用户在ComboBox上进行此类选择后切换节点(使用前面定义的ListView),则ComboBox不再显示新值,但SelectedItem
是正确的。如果用户然后更改ListView AGAIN中的所选项目,则它开始显示正确的值,并且一直很好,直到用户再次使用组合框混乱。
现在我早些时候说过,当ComboBox发生变化时我的模型没有被更新,所以我创建了一个事件处理程序来为我更新模型(你可以在ComboBox的定义中看到这一点)。这被定义为可能的
private void comboBoxTopCam_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
CameraViewInfo selCam = comboBoxTopCam.SelectedItem as CameraViewInfo;
if (selCam != null)
{
OTNode selNode = lvNodes.SelectedItem as OTNode;
if (selCam.Name == "None")
selNode.NodeInfo.Camera1 = new CameraViewInfo();
else
selNode.NodeInfo.Camera1 = selCam; // <- This line affects the behavior
}
}
当我注释掉上面列表中的标记行时,ComboBox会在SelectionBox中显示正确的项目,但不会更新我的模型(例如CurrentNode.NodeInfo.Camera1
未更改)。当我使用lvNodes.SelectedItem
或当我使用CurrentCamera
(数据绑定属性)时,会发生这种情况,它没有区别。
我知道这是一个非常奇怪的问题,如果有人想要更多信息(数据绑定的调试输出,转换器的代码,有关相等运算符的信息等),我会尽力解释它,我很乐意提供它,如果有必要的话,我会愿意上传一段显示奇怪行为的视频,因为它有点难以从文本中理解。
更新
public class EnsureBlankConterter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is CameraViewInfo)
{
if ((value as CameraViewInfo).Name == "")
{
return new CameraViewInfo()
{
Name = "None"
};
}
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is CameraViewInfo)
{
if ((value as CameraViewInfo).Name == "None")
{
return new CameraViewInfo();
}
}
return value;
}
}
PresentationTraceSource.High
在加载时:
System.Windows.Data Warning: 54 : Created BindingExpression (hash=45045097) for Binding (hash=10919470)
System.Windows.Data Warning: 56 : Path: 'CurrentNode.NodeInfo.Camera1'
System.Windows.Data Warning: 60 : BindingExpression (hash=45045097): Attach to System.Windows.Controls.ComboBox.SelectedItem (hash=34909671)
System.Windows.Data Warning: 65 : BindingExpression (hash=45045097): Resolving source
System.Windows.Data Warning: 68 : BindingExpression (hash=45045097): Found data context element: ComboBox (hash=34909671) (OK)
System.Windows.Data Warning: 76 : BindingExpression (hash=45045097): Activate with root item ConfigurationWindow (hash=22010384)
System.Windows.Data Warning: 105 : BindingExpression (hash=45045097): At level 0 using cached accessor for ConfigurationWindow.CurrentNode: RuntimePropertyInfo(CurrentNode)
System.Windows.Data Warning: 102 : BindingExpression (hash=45045097): Replace item at level 0 with ConfigurationWindow (hash=22010384), using accessor RuntimePropertyInfo(CurrentNode)
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 0 from ConfigurationWindow (hash=22010384) using RuntimePropertyInfo(CurrentNode): <null>
System.Windows.Data Warning: 104 : BindingExpression (hash=45045097): Item at level 1 is null - no accessor
System.Windows.Data Warning: 101 : BindingExpression (hash=45045097): Replace item at level 2 with {NullDataItem}
System.Windows.Data Warning: 78 : BindingExpression (hash=45045097): TransferValue - got raw value {DependencyProperty.UnsetValue}
System.Windows.Data Warning: 86 : BindingExpression (hash=45045097): TransferValue - using fallback/default value <null>
System.Windows.Data Warning: 87 : BindingExpression (hash=45045097): TransferValue - using final value <null>
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 0 from ConfigurationWindow (hash=22010384) using RuntimePropertyInfo(CurrentNode): OTNode (hash=59090892)
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 0 from ConfigurationWindow (hash=22010384) using RuntimePropertyInfo(CurrentNode): OTNode (hash=59090892)
System.Windows.Data Warning: 106 : BindingExpression (hash=45045097): At level 1 - for OTNode.NodeInfo found accessor ReflectPropertyDescriptor(NodeInfo)
System.Windows.Data Warning: 102 : BindingExpression (hash=45045097): Replace item at level 1 with OTNode (hash=59090892), using accessor ReflectPropertyDescriptor(NodeInfo)
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 1 from OTNode (hash=59090892) using ReflectPropertyDescriptor(NodeInfo): OTNodeInfo (hash=34742292)
System.Windows.Data Warning: 106 : BindingExpression (hash=45045097): At level 2 - for OTNodeInfo.Camera1 found accessor ReflectPropertyDescriptor(Camera1)
System.Windows.Data Warning: 102 : BindingExpression (hash=45045097): Replace item at level 2 with OTNodeInfo (hash=34742292), using accessor ReflectPropertyDescriptor(Camera1)
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 2 from OTNodeInfo (hash=34742292) using ReflectPropertyDescriptor(Camera1): CameraViewInfo (hash=29245900)
System.Windows.Data Warning: 78 : BindingExpression (hash=45045097): TransferValue - got raw value CameraViewInfo (hash=29245900)
System.Windows.Data Warning: 80 : BindingExpression (hash=45045097): TransferValue - user's converter produced CameraViewInfo (hash=29245900)
System.Windows.Data Warning: 87 : BindingExpression (hash=45045097): TransferValue - using final value CameraViewInfo (hash=29245900)
在选择框中未显示的组合框上进行选择后:
System.Windows.Data Warning: 88 : BindingExpression (hash=45045097): Update - got raw value CameraViewInfo (hash=7936647)
System.Windows.Data Warning: 90 : BindingExpression (hash=45045097): Update - user's converter produced CameraViewInfo (hash=7936647)
System.Windows.Data Warning: 92 : BindingExpression (hash=45045097): Update - using final value CameraViewInfo (hash=7936647)
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 0 from ConfigurationWindow (hash=22010384) using RuntimePropertyInfo(CurrentNode): OTNode (hash=59090892)
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 1 from OTNode (hash=59090892) using ReflectPropertyDescriptor(NodeInfo): OTNodeInfo (hash=22129877)
将ListView切换到新节点,选择框仍未更新:
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 0 from ConfigurationWindow (hash=22010384) using RuntimePropertyInfo(CurrentNode): OTNode (hash=63206919)
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 0 from ConfigurationWindow (hash=22010384) using RuntimePropertyInfo(CurrentNode): OTNode (hash=63206919)
System.Windows.Data Warning: 106 : BindingExpression (hash=45045097): At level 1 - for OTNode.NodeInfo found accessor ReflectPropertyDescriptor(NodeInfo)
System.Windows.Data Warning: 102 : BindingExpression (hash=45045097): Replace item at level 1 with OTNode (hash=63206919), using accessor ReflectPropertyDescriptor(NodeInfo)
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 1 from OTNode (hash=63206919) using ReflectPropertyDescriptor(NodeInfo): OTNodeInfo (hash=35582358)
System.Windows.Data Warning: 106 : BindingExpression (hash=45045097): At level 2 - for OTNodeInfo.Camera1 found accessor ReflectPropertyDescriptor(Camera1)
System.Windows.Data Warning: 102 : BindingExpression (hash=45045097): Replace item at level 2 with OTNodeInfo (hash=35582358), using accessor ReflectPropertyDescriptor(Camera1)
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 2 from OTNodeInfo (hash=35582358) using ReflectPropertyDescriptor(Camera1): CameraViewInfo (hash=49590542)
System.Windows.Data Warning: 78 : BindingExpression (hash=45045097): TransferValue - got raw value CameraViewInfo (hash=49590542)
System.Windows.Data Warning: 80 : BindingExpression (hash=45045097): TransferValue - user's converter produced CameraViewInfo (hash=49590542)
System.Windows.Data Warning: 87 : BindingExpression (hash=45045097): TransferValue - using final value CameraViewInfo (hash=49590542)
使用DID更新选择框的列表视图切换节点后:
System.Windows.Data Warning: 99 : BindingExpression (hash=51217614): GetValue at level 0 from ConfigurationWindow (hash=63245828) using RuntimePropertyInfo(CurrentNode): OTNode (hash=8023662)
System.Windows.Data Warning: 99 : BindingExpression (hash=51217614): GetValue at level 0 from ConfigurationWindow (hash=63245828) using RuntimePropertyInfo(CurrentNode): OTNode (hash=8023662)
System.Windows.Data Warning: 106 : BindingExpression (hash=51217614): At level 1 - for OTNode.NodeInfo found accessor ReflectPropertyDescriptor(NodeInfo)
System.Windows.Data Warning: 102 : BindingExpression (hash=51217614): Replace item at level 1 with OTNode (hash=8023662), using accessor ReflectPropertyDescriptor(NodeInfo)
System.Windows.Data Warning: 99 : BindingExpression (hash=51217614): GetValue at level 1 from OTNode (hash=8023662) using ReflectPropertyDescriptor(NodeInfo): OTNodeInfo (hash=21425964)
System.Windows.Data Warning: 106 : BindingExpression (hash=51217614): At level 2 - for OTNodeInfo.Camera1 found accessor ReflectPropertyDescriptor(Camera1)
System.Windows.Data Warning: 102 : BindingExpression (hash=51217614): Replace item at level 2 with OTNodeInfo (hash=21425964), using accessor ReflectPropertyDescriptor(Camera1)
System.Windows.Data Warning: 99 : BindingExpression (hash=51217614): GetValue at level 2 from OTNodeInfo (hash=21425964) using ReflectPropertyDescriptor(Camera1): CameraViewInfo (hash=6049320)
System.Windows.Data Warning: 78 : BindingExpression (hash=51217614): TransferValue - got raw value CameraViewInfo (hash=6049320)
System.Windows.Data Warning: 80 : BindingExpression (hash=51217614): TransferValue - user's converter produced CameraViewInfo (hash=6049320)
System.Windows.Data Warning: 87 : BindingExpression (hash=51217614): TransferValue - using final value CameraViewInfo (hash=6049320)
答案 0 :(得分:1)
我认为您的问题与您绑定SelectedItem
的方式有关:
<ComboBox ...
SelectedItem="{Binding Path=CurrentNode.NodeInfo.Camera1,
Converter={StaticResource EnsureBlank}, Mode=TwoWay}" ...
如果内存正常,SelectedItem
是一个属性(Text
是另一个属性)(默认情况下)仅在焦点丢失时推送更新。
将UpdateSourceTrigger="PropertyChanged"
添加到绑定以强制更新更频繁地发生。你不应该需要你的活动。
答案 1 :(得分:0)
您的转换器会创建一个新对象,而ItemTemplate的TextBlock中的文本将保持与原始对象的绑定。因此,当您更改新对象的Name属性时,它显然不会改变。
答案 2 :(得分:0)
好的,所以我最终完全摆脱了数据绑定,并使用一个非常winforms样式的事件模型来更新我的数据。我仍然无法弄清楚为什么数据绑定不起作用,如果有人使用数据绑定解决方案我会接受这个答案。