简体   繁体   English

在WPF中的多个列表框上的TwoWay绑定到ListBox SelectedItem

[英]TwoWay Binding to ListBox SelectedItem on more than one list box in WPF

I have a scenario where I have a globally available Properties window (similar to the Properties window in Visual Studio), which is bound to a SelectedObject property of my model. 我有一个场景,我有一个全局可用的属性窗口(类似于Visual Studio中的属性窗口),它绑定到我的模型的SelectedObject属性。 I have a number of different ways to browse and select objects, so my first attempt was to bind them to SelectedObject directly. 我有许多不同的浏览和选择对象的方法,所以我的第一次尝试是将它们直接绑定到SelectedObject。 For example: 例如:

<ListBox ItemsSource="{Binding ActiveProject.Controllers}" 
SelectedItem="{Binding SelectedObject, Mode=TwoWay}"/>

<ListBox ItemsSource="{Binding ActiveProject.Machines}" 
SelectedItem="{Binding SelectedObject, Mode=TwoWay}"/>

This works well when I have more than one item in each list, but it fails if a list has only one item. 当每个列表中有多个项目时,这很有效,但如果列表只有一个项目,则会失败。 When I select the item, SelectedObject is not updated, since the list still thinks its original item was selected. 当我选择项目时,SelectedObject不会更新,因为列表仍然认为其原始项目已被选中。 I believe this happens because the two way binding simply ignores the update from source when SelectedObject is not an object in the list, leaving the list's SelectedItem unchanged. 我相信这是因为当SelectedObject不是列表中的对象时,双向绑定只是忽略源的更新,而是保持列表的SelectedItem不变。 In this way, the bindings become out of sync. 这样,绑定变得不同步。

Does anybody know of a way to make sure the list boxes reset their SelectedItem when the SelectedObject is not in the list? 当SelectedObject不在列表中时,是否有人知道确保列表框重置其SelectedItem的方法? Is there a better way to do this that doesn't suffer from this problem? 有没有更好的方法来做到这个没有这个问题?

Dan's answer helped me to solve my problem too. Dan的回答帮助我解决了我的问题。 It looks as though the key is to have bound objects rebind first to a null value and then again to the new value. 看起来好像关键是绑定对象首先重新绑定为空值,然后再重新绑定到新值。

Not having Postsharp in my solution or any need to maintain a list of selected objects, this is the only code that I needed. 在我的解决方案中没有Postsharp或者需要维护所选对象的列表,这是我需要的唯一代码。

    Public Property MyProperty() As Object
        Get
            Return Me._MyProperty
        End Get
        Set(value As Object)
            Me._MyProperty = Nothing

            NotifyOfPropertyChange(Function() MyProperty)

            Me._MyProperty = value

            NotifyOfPropertyChange(Function() MyProperty)
        End Set
    End Property

Well, I found a way around the issue, but it makes me slightly ill. 好吧,我找到了绕过这个问题的方法,但这让我有些不适。 I modified the SelectedObject property in my model to this: 我将模型中的SelectedObject属性修改为:

public Object SelectedObject
{
    get
    {
        return _selectedObject;
    }
    set
    {
        if (value != _selectedObject)
        {
            //HACK
            //Pulse 'null' between changes to reset listening list controls
            if (value != null)
                SelectedObject = null;

            if (_selectedObject != null)
                SelectedObjects.Remove(_selectedObject);

            _selectedObject = value;
            if (value != null)
                SelectedObjects.Add(value);
        }
    }
}

This forces all of the data bound list controls to reset their SelectedItem to null before we update to the 'real' SelectedObject. 这会强制所有数据绑定列表控件在我们更新为“真正的”SelectedObject之前将其SelectedItem重置为null。 On a side note, the NotifyPropertyChanged stuff is being handled by PostSharp, in case you were wondering why it's missing. 另外,PostSharp正在处理NotifyPropertyChanged的内容,以防你想知道为什么它丢失了。

I'd prefer a less hackish solution, if possible, but I do like the fact that this keeps the bindings clean in the XAML (no change required.) 如果可能的话,我更喜欢一个不太讨厌的解决方案,但我确实喜欢这样一个事实:这样可以保持XAML中的绑定清晰(无需更改)。

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

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