我一直在试图看看是否有一种简单/巧妙的方式来实现与ListBox.SelectedItems的绑定。如果你已经尝试过自己,你会知道,使用BindingExtension的标记绑定将不起作用 - 该属性不支持它。因此,您需要为SelectionChanged配置一个处理程序并尝试该路线。我得到的最接近的是这篇文章:
http://alexshed.spaces.live.com/blog/cns!71C72270309CE838!149.entry
它在一个方便的附加属性中实现了所有必需的C#。但它实现了“绑定”作为单向,目标到源。我想要双向绑定。
有任何想法吗?
发布于 2018-04-11 16:38:32
我正在为此寻找解决方案,而且这个提议似乎过于复杂。因此,下面是一个新的双向绑定解决方案,它仅限于附加属性,并使用弱事件处理来监视定义的依赖属性中的更改。我没有花时间做这个防弹,但它确实有效。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
namespace WpfApplication2
{
public class ListBoxHelper
{
private static Dictionary<int, bool> SynchToDPInProcessDictionary = new Dictionary<int, bool>();
private static Dictionary<int, bool> SynchToLBInProcessDictionary = new Dictionary<int, bool>();
public static readonly DependencyProperty SelectedItemsProperty =
DependencyProperty.RegisterAttached("SelectedItems", typeof(IList), typeof(ListBoxHelper),
new FrameworkPropertyMetadata((IList)null,
new PropertyChangedCallback(OnSelectedItemsChanged)));
public static IList GetSelectedItems(DependencyObject d)
{
return (IList)d.GetValue(SelectedItemsProperty);
}
public static void SetSelectedItems(DependencyObject d, IList value)
{
d.SetValue(SelectedItemsProperty, value);
}
private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var listBox = d as ListBox;
if (listBox == null)
throw new InvalidOperationException("ListBoxHelper should only be used with ListBox or ListBox derived classes (like ListView).");
int hashcode = listBox.GetHashCode();
// Gets set on the initial binding.
if (!SynchToDPInProcessDictionary.ContainsKey(hashcode))
{
SynchToDPInProcessDictionary[hashcode] = false;
SynchToLBInProcessDictionary[hashcode] = false;
var observableCollection = GetSelectedItems(listBox) as INotifyCollectionChanged;
if (observableCollection != null)
{
// Create a weak CollectionChanged event handler on the SelectedItems property
// that synchronizes the collection back to the listbox.
CollectionChangedEventManager.AddHandler(observableCollection,
delegate(object sender, NotifyCollectionChangedEventArgs e2)
{
SyncToLBSelectedItems(GetSelectedItems(d), (ListBox)d);
});
}
}
SynchToDPSelectedItems(listBox);
listBox.SelectionChanged += delegate
{
SynchToDPSelectedItems(listBox);
};
}
private static void SynchToDPSelectedItems(ListBox listBox)
{
int hashcode = listBox.GetHashCode();
if (SynchToLBInProcessDictionary[hashcode]) return;
SynchToDPInProcessDictionary[hashcode] = true;
try
{
IList dpSelectedItems = GetSelectedItems(listBox);
dpSelectedItems.Clear();
if (listBox.SelectedItems != null)
{
foreach (var item in listBox.SelectedItems)
dpSelectedItems.Add(item);
}
}
finally
{
SynchToDPInProcessDictionary[hashcode] = false;
}
}
private static void SyncToLBSelectedItems(IList dpSelectedItems, ListBox listBox)
{
int hashcode = listBox.GetHashCode();
if (SynchToDPInProcessDictionary[hashcode]) return;
SynchToLBInProcessDictionary[hashcode] = true;
try
{
listBox.SelectedItems.Clear();
if (dpSelectedItems != null)
{
foreach (var item in dpSelectedItems)
listBox.SelectedItems.Add(item);
}
}
finally
{
SynchToLBInProcessDictionary[hashcode] = false;
}
}
}
}
https://stackoverflow.com/questions/-100008069
复制相似问题