3

我有一个ListBox绑定到MyCollection的类型IEnumerable<string>

 <ListBox x:Name="ListBox" ItemsSource="{Binding MyCollection, Mode=OneWay}" SelectionMode="Multiple"/>

我有另一个List<string> SubCollection包含一个子集MyCollection

每当SubCollection发生变化时,我希望SelectedItems根据SubCollection

是否有任何BindingBehaviour任何其他方式来实现这一点?

编辑:

假设我ListBox一定要MyCollection { "Orange", "Mango", "Stawberry", "Pineapple" }

假设我按下一个按钮从数据库加载数据,结果是“Orange”、“Mango”,然后放入 to 中SubCollectionListBox现在应该有 "Orange", "Mango" 作为它的SelectedItems.

4

6 回答 6

5

我有一个建议给你。

您可以绑定IsSelectedListBoxItem.

为此,您必须使用collection of objects(比如说MyListBoxItem)而不是字符串集合。

public class  MyListBoxItem
{
    public string Description { get; set; }
    public bool IsSelected { get; set; }
}

使用这个类的“ ”属性IsSelectedMyListBoxItem绑定.IsSelectedListBoxItem

例如:在您查看模型中,

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>
于 2013-03-20T09:31:16.240 回答
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);
                }
            }
        }
    }
}

Xaml 用法:

<ListBox ItemsSource="{Binding Items}" SelectionMode="Multiple"
         local:ListBoxExtensions.SelectedItemList="{Binding SelectedItems}" />


演示:

如果你想测试的工作示例:

xml:

<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);
                    }
                }
            }
        }
    }
}

结果:

在此处输入图像描述

于 2013-03-21T06:22:28.927 回答
2

标准数据绑定不起作用,因为 SelectedItems 属性是只读的。

一种简单的方法是手动迭代 MyCollection 并根据 SubCollection 中的项目设置每个项目的 IsSelected 属性。为此,MyCollection 列表中的项目应包含从 ListBoxItem 继承的对象,这将公开 IsSelected 属性。

这是一个示例 WPF 应用程序来演示它:

单击按钮将根据 SubCollection 列表中的项目更新所选项目。现在我已经硬编码了 SubCollection 列表的值。

根据您的实现,您可以更新您的 SubCollection,并将按钮单击事件中的代码适当地挂钩到任何其他事件。(例如将 SubCollection 列表设置为 ObservableCollection 并挂钩到 ObservableCollection.CollectionChange)

主窗口.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>

主窗口.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;
        }
    }
}
于 2013-03-21T06:47:11.450 回答
1

查看这篇博文:how-to-databind-to-selecteditems。有一个附有代码的演示项目。

于 2013-03-18T10:05:21.777 回答
1

使用SelectedValueListBox 的“”属性。(因为您正在使用字符串集合来绑定列表框。)

  1. 在您的视图模型中定义一个字符串类型属性(比如说MySelectedValue)。
  2. 然后将其绑定到SelectedValue两个列表框的“”属性。(记得Mode = TwoWay在你的主列表框中设置)
  3. 假设当您在子集合列表框中选择一个项目时将执行一个方法。(必须触发SelectionChanged子集合列表框的事件)
  4. 就是这样。

所以。你要做的是:

使用相同的属性绑定两个列表框的“SelectedValue”属性。

假设您想将一组对象绑定到列表框。然后使用SelectedItem属性来完成这个任务。

于 2013-03-18T11:33:58.047 回答
0

如果您知道要选择的索引号,可以使用

int[] index = {1, 2, 5};
for( int i in index) 
{    
   listBox.SetSelected( i, true );
}
于 2015-10-01T06:40:43.223 回答