質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

2回答

1673閲覧

WPF ItemsControl 変更された要素を取得したい

Hottopia

総合スコア16

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2023/01/05 05:50

前提

C# WPF(Prism使用)にて、16個のチェックボックスを格納したItemsControlを作成しました。

実現したいこと

ItemsControl内のCheckboxに変更があった際、変更されたチェックボックスにバインドされている
Bitクラスのプロパティ(Area,BitNumber,IsSet)を使用して、EventNumberオブジェクトを生成する処理を行いたい。

該当のソースコード

Xaml

<Window x:Class="Sample.Views.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:prism="http://prismlibrary.com/" xmlns:viewmodels="clr-namespace:Sample.ViewModels" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" d:DataContext="{d:DesignInstance Type=viewmodels:MainWindowViewModel}" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" prism:ViewModelLocator.AutoWireViewModel="True" Title="Sample" Height="1000" Width="1000" > <Grid> <ContentControl prism:RegionManager.RegionName="ContentRegion" /> <Grid> <ItemsControl x:Name="Area1" ItemsSource="{Binding Collection}" > <ItemsControl.ItemTemplate> <DataTemplate> <CheckBox IsChecked="{Binding IsSet,Mode=TwoWay}" FlowDirection="RightToLeft"> <TextBlock > <Run Text=""/><Run Text="{Binding BitNumber, Mode=OneTime}"/> </TextBlock> </CheckBox> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <UniformGrid Rows="1"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl> </Grid> </Grid> </Window>

ViewModel.cs

using Sample.Models; using Prism.Mvvm; using System; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; namespace Sample.ViewModels { public class MainWindowViewModel : BindableBase { public MainWindowViewModel() { } private string _eventNumber; public string EventNumber { get { return _eventNumber; } set { SetProperty(ref _eventNumber, value); } } /// <summary> /// ItemsControl生成用ObservableCollection /// </summary> public ObservableCollection<Bit> Collection { get; } = new ObservableCollection<Bit>(Enumerable.Range(0, 16).Select(v => new Bit(v,1))); private DelegateCommand _collectionChanged; public DelegateCommand CollectionChanged => _changed ?? (_collectionChanged = new DelegateCommand(ExecuteCollectionChanged)); void ExecuteCollectionChanged() { //_eventNumberを生成したい。コマンドだと変更された要素を特定できない? } } }

Bit.cs

using Prism.Mvvm; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Sample.Models { public class Bit : BindableBase { private bool _isSet; public int Area { get; } public int BitNumber { get; } public bool IsSet { get { return _isSet; } set { SetProperty(ref _isSet, value); } } public Bit(int bitNumber,int area) { BitNumber = bitNumber; Area = area; } } }

EventNumber.cs

using Prism.Mvvm; using System; using System.Collections.Generic; using System.Linq; using System.Reflection.Metadata.Ecma335; using System.Text; using System.Threading.Tasks; namespace Sample.Models { internal class EventNumber { private readonly int _value; public int Value { get { return _value; } } public EventNumber(int wordArea, int inputMap, bool contact) { } } }

試したこと

コマンドでできそうな気がしましたが、変更された要素のみを渡す処理が思いつきません。
それともコマンドを使用するという発想から間違えているのでしょうか?
自分の検索力の無さによる疑問かもしれませんが、ご教授お願い致します。

補足情報(FW/ツールのバージョンなど)

Windows10
Visual Studio2022
Prism 8.1.97

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ItemsControl内のCheckboxに変更があった際、変更されたチェックボックスにバインドされている
Bitクラスのプロパティ(Area,BitNumber,IsSet)を使用して、EventNumberオブジェクトを生成する処理を行いたい。

INotifyPropertyChangedINotifyCollectionChangedを混同しないようにしてください。
コレクションの増減と中のアイテムのプロパティ変更はまったく別個のものです。
INotifyPropertyChanged インターフェイス (System.ComponentModel) | Microsoft Learn
INotifyCollectionChanged インターフェイス (System.Collections.Specialized) | Microsoft Learn

コマンドでできそうな気がしましたが、変更された要素のみを渡す処理が思いつきません。
それともコマンドを使用するという発想から間違えているのでしょうか?

それが正解じゃないですかね?
単純にCheckBoxに、コマンドをバインドすればいいと思います。

xml

1<Window 2 x:Class="Qrye9n05uuprppq.Views.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 7 xmlns:prism="http://prismlibrary.com/" 8 xmlns:viewmodels="clr-namespace:Qrye9n05uuprppq.ViewModels" 9 Title="Sample" 10 Width="1000" 11 Height="1000" 12 d:DataContext="{d:DesignInstance viewmodels:MainWindowViewModel, IsDesignTimeCreatable=True}" 13 prism:ViewModelLocator.AutoWireViewModel="True" 14 mc:Ignorable="d"> 15 <Grid> 16 <!--<ContentControl prism:RegionManager.RegionName="ContentRegion" />--> 17 <ItemsControl x:Name="Area1" VerticalAlignment="Top" ItemsSource="{Binding Collection}"> 18 <ItemsControl.ItemTemplate> 19 <DataTemplate> 20 <CheckBox 21 VerticalContentAlignment="Center" 22 Command="{Binding DataContext.CheckChangedCommand, ElementName=Area1}" 23 CommandParameter="{Binding}" 24 FlowDirection="RightToLeft" 25 IsChecked="{Binding IsSet}"> 26 <!-- [XAML Checkbox Label Alignment - Visual Studio Feedback](https://developercommunity.visualstudio.com/t/xaml-checkbox-label-alignment/850708) --> 27 <CheckBox.Resources> 28 <Style TargetType="Path"> 29 <Setter Property="FlowDirection" Value="LeftToRight" /> 30 </Style> 31 </CheckBox.Resources> 32 <TextBlock Text="{Binding BitNumber}" /> 33 </CheckBox> 34 </DataTemplate> 35 </ItemsControl.ItemTemplate> 36 <ItemsControl.ItemsPanel> 37 <ItemsPanelTemplate> 38 <UniformGrid Rows="1" /> 39 </ItemsPanelTemplate> 40 </ItemsControl.ItemsPanel> 41 </ItemsControl> 42 </Grid> 43</Window>

cs

1using System.Collections.ObjectModel; 2using System.Diagnostics; 3using System.Linq; 4using Prism.Commands; 5using Prism.Mvvm; 6using Qrye9n05uuprppq.Models; 7 8 9namespace Qrye9n05uuprppq.ViewModels 10{ 11 public class MainWindowViewModel : BindableBase 12 { 13 public string EventNumber { get => _eventNumber; set => SetProperty(ref _eventNumber, value); } 14 private string _eventNumber; 15 16 /// <summary>ItemsControl生成用ObservableCollection</summary> 17 public ObservableCollection<Bit> Collection { get; } 18 = new(Enumerable.Range(0, 16).Select(v => new Bit(v, 1))); 19 20 public DelegateCommand<Bit> CheckChangedCommand => _checkChangedCommand ??= new(ExecuteCheckChanged); 21 private DelegateCommand<Bit> _checkChangedCommand; 22 23 public MainWindowViewModel() { } 24 25 private void ExecuteCheckChanged(Bit bit) 26 { 27 Debug.WriteLine(bit); 28 } 29 } 30} 31 32namespace Qrye9n05uuprppq.Models 33{ 34 public class Bit : BindableBase 35 { 36 public int Area { get; } 37 38 public int BitNumber { get; } 39 40 public bool IsSet { get => _isSet; set => SetProperty(ref _isSet, value); } 41 private bool _isSet; 42 43 public Bit(int bitNumber, int area) 44 { 45 BitNumber = bitNumber; 46 Area = area; 47 } 48 49 public override string ToString() => $"Area:{Area}, BitNumber:{BitNumber}, IsSet:{IsSet}"; 50 } 51}

投稿2023/01/05 09:25

編集2023/01/05 10:50
TN8001

総合スコア9317

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

MainWindowViewModel の ObservableCollection<Bit> Collection に対して ObserveElementProperty を使えばコレクション内要素のプロパティ変更通知を受け取れます。

cs

1IDisposable bitObserver = Collection 2 .ObserveElementProperty(x => x.IsSet) 3 .Subscribe(x => HandleBitChanged(x.Instance)); 4 5// TODO: bitObserver.Dispose() を 6// UnloadやNavigatingFromのタイミングで呼び出して 7// 購読解除を完了させる

cs

1void HandleBitChanged(Bit bit) 2{ 3 Debug.WriteLine($"{bit.BitArea} {bit.BitNumber}: {bit.IsSet}"); 4}

参考

ObservableCollection<T> の型引数 T が INotifyPropertyChanged の場合に利用できる拡張メソッドです。ObservableCollection<T> の全ての要素の PropertyChanged イベントを監視できます。

投稿2023/01/05 06:39

tor4kichi

総合スコア763

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問