WPFでReactiveCollectionのオブジェクトをListboxのデータソースとしてバインドする方法を試してみました。
ReactiveCollectionを使うことでUI側の制約をあまり気にすることなく要素の追加削除移動が出来ることが確認できました。
ReactiveCollectionを使うことでUI側の制約をあまり気にすることなく要素の追加削除移動が出来ることが確認できました。
実行環境
Windows10 2004
dotnet –version 5.0.104
Visual Studio Code
PowerShell 5.1
dotnet –version 5.0.104
Visual Studio Code
PowerShell 5.1
プロジェクトの作成
mkdir プロジェクト名
cd プロジェクト名
dotnet new wpf
dotnet add package Microsoft.Xaml.Behaviors.Wpf
dotnet add package ReactiveProperty.WPF
code .
ソースコード
ファイル名:MainWindow.xaml
<Window x:Class="WpfSample23Listbox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfSample23Listbox"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Grid>
<StackPanel Margin="10" >
<Label>追加項目の選択</Label>
<ComboBox
DisplayMemberPath="Name"
SelectedValuePath="Id"
SelectedValue="{Binding ItemsSelected.Value}"
SelectedIndex="{Binding ItemsSelectedIndex.Value}"
ItemsSource="{Binding Items}" />
<WrapPanel
Orientation="Horizontal"
Margin="10">
<Button Content="追加"
Command="{Binding AddCommand}" />
<Button Content="削除"
Command="{Binding RemoveCommand}" />
<Button Content="上へ"
Command="{Binding UpCommand}" />
<Button Content="下へ"
Command="{Binding DownCommand}" />
</WrapPanel>
<ListBox
DisplayMemberPath="Name"
SelectedValuePath="Id"
SelectedIndex="{Binding MethodListIndex.Value}"
ItemsSource="{Binding MethodList}">
</ListBox>
</StackPanel>
</Grid>
</Window>
ファイル名:MainWindowViewModel.cs
using System;
using System.ComponentModel;
using Reactive.Bindings;
namespace WpfSample23Listbox
{
public class MainWindowViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public ReactiveProperty<Guid> ItemsSelected { get; set; } = new ReactiveProperty<Guid>();
public ReactiveProperty<int> ItemsSelectedIndex { get; set; } = new ReactiveProperty<int>();
public ReactiveCollection<Item> Items { get; set; } = new ReactiveCollection<Item>();
public ReactiveProperty<int> MethodListIndex { get; set; } = new ReactiveProperty<int>();
public ReactiveCollection<Item> MethodList { get; set; } = new ReactiveCollection<Item>();
public ReactiveCommand AddCommand { get; }
public ReactiveCommand RemoveCommand { get; }
public ReactiveCommand UpCommand { get; }
public ReactiveCommand DownCommand { get; }
public MainWindowViewModel()
{
Items.AddOnScheduler(new Item("ぼかし"));
Items.AddOnScheduler(new Item("アンシャープマスキング"));
Items.AddOnScheduler(new Item("ノンローカルミーン"));
AddCommand = new ReactiveCommand()
.WithSubscribe(()=>{
var name = Items[ItemsSelectedIndex.Value].Name;
MethodList.AddOnScheduler(new Item(name));
});
RemoveCommand = new ReactiveCommand()
.WithSubscribe(()=>{
if (MethodList.Count == 0) return;
if (MethodListIndex.Value < 0) return;
MethodList.RemoveAtOnScheduler(MethodListIndex.Value);
});
UpCommand = new ReactiveCommand()
.WithSubscribe(()=>{
if (MethodList.Count <= 1) return;
if (MethodListIndex.Value <= 0) return;
MethodList.MoveOnScheduler(MethodListIndex.Value, MethodListIndex.Value-1);
MethodListIndex.Value -= 1;
});
DownCommand = new ReactiveCommand()
.WithSubscribe(()=>{
if (MethodList.Count <= 1) return;
if (MethodListIndex.Value >= (MethodList.Count-1)) return;
MethodList.MoveOnScheduler(MethodListIndex.Value, MethodListIndex.Value+1);
MethodListIndex.Value += 1;
});
}
}
}
ファイル名:Item.cs
using System;
namespace WpfSample23Listbox
{
public class Item
{
public string Name {get; set;}
public Guid Id {get; set;}
public Item()
{
this.Id = Guid.NewGuid();
}
public Item(string name) : this()
{
this.Name = name;
}
}
}
コメント