我有一个ListBox
绑定到MyCollection
类型的IEnumerable<string>
。
<ListBox x:Name="ListBox" ItemsSource="{Binding MyCollection, Mode=OneWay}" SelectionMode="Multiple"/>
我有另一个List<string>
SubCollection
,其中包含MyCollection
每当SubCollection
发生变化时,我都希望根据SelectedItems
SubCollection
是否有Binding
,Behaviour
或其他任何方式来实现此目标?
修改
假设我ListBox
绑定MyCollection
{ "Orange", "Mango", "Stawberry", "Pineapple" }
假设我按下按钮从数据库加载数据,结果为“橙色”,“芒果”,然后放入SubCollection
。 ListBox
现在应该将“橙色”,“芒果”作为其SelectedItems
。
答案 0 :(得分:5)
我有一个建议。
您可以绑定到&#34; IsSelected
&#34; ListBoxItem
的属性。
要做到这一点,你必须使用collection of objects
(让我们说MyListBoxItem
)而不是字符串集合。
public class MyListBoxItem
{
public string Description { get; set; }
public bool IsSelected { get; set; }
}
使用此&#34; IsSelected
&#34; MyListBoxItem
类的属性绑定&#34; IsSelected
&#34; ListBoxItem
的财产。
例如:在您查看模型时,
this.MyCollection = new ObservableCollection<MyListBoxItem>();
MyListBoxItem item1 = new MyListBoxItem()
item1.Description = "Mango";
item1.IsSelected = true;
MyCollection .add(item1);
MyListBoxItem item2 = new MyListBoxItem()
item2 .Description = "Orange";
item2 .IsSelected = false;
MyCollection .add(item2 );
XAML(在ListBox
内)
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
</Style>
</ListBox.ItemContainerStyle>
答案 1 :(得分:4)
您可以为List
创建AttachedProperty
ListBox
,以便在更改列表时将项目添加到ListBox.SelectedItems
。
AttachedProperty
解决方案让WPF
保持清洁,并保持MVVM
模式。此外,它还可以在您的所有项目中重复使用此功能:)
以下是一个例子:
public static class ListBoxExtensions
{
// Using a DependencyProperty as the backing store for SearchValue. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SelectedItemListProperty =
DependencyProperty.RegisterAttached("SelectedItemList", typeof(IList), typeof(ListBoxExtensions),
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnSelectedItemListChanged)));
public static IList GetSelectedItemList(DependencyObject obj)
{
return (IList)obj.GetValue(SelectedItemListProperty);
}
public static void SetSelectedItemList(DependencyObject obj, IList value)
{
obj.SetValue(SelectedItemListProperty, value);
}
private static void OnSelectedItemListChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var listbox = d as ListBox;
if (listbox != null)
{
listbox.SelectedItems.Clear();
var selectedItems = e.NewValue as IList;
if (selectedItems != null)
{
foreach (var item in selectedItems)
{
listbox.SelectedItems.Add(item);
}
}
}
}
}
<ListBox ItemsSource="{Binding Items}" SelectionMode="Multiple"
local:ListBoxExtensions.SelectedItemList="{Binding SelectedItems}" />
如果你想测试的工作示例:
的Xaml:
<Window x:Class="WpfApplication17.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication17"
Title="MainWindow" Height="227" Width="170" Name="UI">
<Grid DataContext="{Binding ElementName=UI}">
<ListBox ItemsSource="{Binding Items}" SelectionMode="Multiple"
local:ListBoxExtensions.SelectedItemList="{Binding SelectedItems}" Margin="0,0,0,37" >
<ListBox.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="{x:Static SystemColors.HighlightColor}" />
<Style TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.Resources>
</ListBox>
<Button Content="Populate SelectedItemList" Click="Button_Click" Height="32" Margin="2,0,1,2" VerticalAlignment="Bottom"/>
</Grid>
</Window>
代码:
namespace WpfApplication17
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
private List<string> _selectedItems = new List<string>();
private ObservableCollection<string> _items = new ObservableCollection<string>
{ "Orange", "Mango", "Stawberry", "Pineapple", "Apple", "Grape", "Banana" };
public MainWindow()
{
InitializeComponent();
}
public ObservableCollection<string> Items
{
get { return _items; }
set { _items = value; }
}
public List<string> SelectedItems
{
get { return _selectedItems; }
set { _selectedItems = value; OnPropertyChanged("SelectedItems"); }
}
private void Button_Click(object sender, RoutedEventArgs e)
{
SelectedItems = new List<string> { "Orange", "Pineapple", "Apple" };
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string e)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(e));
}
}
public static class ListBoxExtensions
{
// Using a DependencyProperty as the backing store for SearchValue. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SelectedItemListProperty =
DependencyProperty.RegisterAttached("SelectedItemList", typeof(IList), typeof(ListBoxExtensions),
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnSelectedItemListChanged)));
public static IList GetSelectedItemList(DependencyObject obj)
{
return (IList)obj.GetValue(SelectedItemListProperty);
}
public static void SetSelectedItemList(DependencyObject obj, IList value)
{
obj.SetValue(SelectedItemListProperty, value);
}
private static void OnSelectedItemListChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var listbox = d as ListBox;
if (listbox != null)
{
listbox.SelectedItems.Clear();
var selectedItems = e.NewValue as IList;
if (selectedItems != null)
{
foreach (var item in selectedItems)
{
listbox.SelectedItems.Add(item);
}
}
}
}
}
}
结果:
答案 2 :(得分:2)
标准数据绑定不起作用,因为SelectedItems属性是只读的。
一种简单的方法是根据SubCollection中的项目手动迭代MyCollection并设置每个项目的IsSelected属性。 为此,MyCollection列表中的项应包含从ListBoxItem继承的对象,该对象将公开IsSelected属性。
以下是一个示例WPF应用程序:
按钮单击将根据SubCollection列表中的项目更新所选项目。现在我已经硬编码了SubCollection列表的值。
根据您的实现,您可以更新您的SubCollection,并将按钮单击事件中的代码适当地挂钩到任何其他事件。(比如将SubCollection列表作为ObservableCollection并挂钩到ObservableCollection.CollectionChange)
<强> MainWindow.xaml 强>
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="250" Width="255">
<Grid>
<StackPanel Orientation="Vertical">
<ListBox x:Name="ListBox" ItemsSource="{Binding MyCollection}" SelectionMode="Extended" Margin="10,10"/>
<Button Content="UpdateSelection" Click="Button_Click" Margin="10,10"/>
</StackPanel>
</Grid>
</Window>
<强> MainWindow.xaml.cs 强>
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
_myCollection = new ObservableCollection<MyListBoxItem>() { new MyListBoxItem("Orange"), new MyListBoxItem("Mango"), new MyListBoxItem("Stawberry"), new MyListBoxItem("Pineapple") };
//Items to be selected on this.MyCollection ListBox
this.SubCollection = new List<string>() { "Pineapple", "Mango" };
this.DataContext = this;
}
private ObservableCollection<MyListBoxItem> _myCollection;
public ObservableCollection<MyListBoxItem> MyCollection
{
get { return _myCollection; }
set
{
this._myCollection = value;
}
}
public IList<string> SubCollection { get; set; }
private void Button_Click(object sender, RoutedEventArgs e)
{
// Clear all the selected items in the ListBox
this.MyCollection.ToList().ForEach(item => item.IsSelected = false);
// SELECT only the items in MySubCollection into this.MyCollection ListBox
this.MyCollection.Where(item => this.SubCollection.Contains(item.Content.ToString())).ToList().ForEach(item => item.IsSelected= true);
}
}
public class MyListBoxItem : ListBoxItem
{
public MyListBoxItem(string displayName)
{
this.Content = displayName;
}
}
}
答案 3 :(得分:1)
查看此博文:how-to-databind-to-selecteditems。有一个附带代码的演示项目。
答案 4 :(得分:1)
使用&#34; SelectedValue
&#34; ListBox的属性。
(因为您正在使用字符串集合来绑定列表框。)
MySelectedValue
)。SelectedValue
&#34;两个列表框的属性。 (记住在主列表框中设置Mode = TwoWay
)SelectionChanged
事件)因此。你要做的是:
使用相同的属性绑定&#34; SelectedValue&#34;两种财产 列表框。
如果您想将一组对象绑定到列表框,请说。
然后使用SelectedItem
属性来完成此任务。
答案 5 :(得分:0)
如果您知道要选择的索引号,可以使用
int[] index = {1, 2, 5};
for( int i in index)
{
listBox.SetSelected( i, true );
}