3

typeListBoxにバインドされている があります。MyCollectionIEnumerable<string>

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

List<string> SubCollectionのサブセットを含む別のものがありますMyCollection

変更するたびに、 に従って強調表示しSubCollectionたいと思いますSelectedItemsSubCollection

Bindingこれを達成するための、Behaviourまたは他の方法はありますか?

編集:

ListBox私はに縛られているとしましょうMyCollection { "Orange", "Mango", "Stawberry", "Pineapple" }

ボタンを押してデータベースからデータをロードすると、結果が「オレンジ」、「マンゴー」になり、これが に配置されたとしSubCollectionます。ListBoxとして「オレンジ」、「マンゴー」が必要SelectedItemsです。

4

6 に答える 6

5

私はあなたに提案があります。

IsSelectedの" "プロパティにバインドできますListBoxItem

これを行うには、文字列のコレクションの代わりにcollection of objects(たとえば)を使用する必要があります。MyListBoxItem

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

クラスのこの" IsSelected"プロパティを使用して、の""プロパティMyListBoxItemをバインドします。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作成できます。ListBoxListBox.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}" />


デモ:

テストしたい場合の作業例:

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

結果:

ここに画像の説明を入力

于 2013-03-21T06:22:28.927 に答える
2

SelectedItems プロパティが読み取り専用であるため、標準のデータ バインディングは機能しません。

簡単な方法の 1 つは、SubCollection の項目に基づいて、MyCollection を手動で繰り返し、各項目の IsSelected プロパティを設定することです。このために、MyCollection リストのアイテムには、IsSelected プロパティを公開する ListBoxItem から継承されたオブジェクトが含まれている必要があります。

これをデモストレーションするためのサンプル 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;
        }
    }
}
于 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( Sub Collection ListBoxのイベントをトリガーする必要があります)
  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 に答える