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

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

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

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

WPF

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

Q&A

解決済

1回答

1073閲覧

ObservableCollectionの要素クラスのプロパティ

unikuma

総合スコア11

C#

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

WPF

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

0グッド

0クリップ

投稿2023/03/21 08:33

前提

WPF、Livetを使用してデスクトップアプリを作っています。
ObservableCollectionを使用したBindingで気になる挙動があったのでお知恵をお借りしたいです。

発生している問題・エラーメッセージ

ListBoxにObservableCollectionをバインドし、DataTemplateで要素を編集できるようにしました。
またComboBoxを用意し、同じコレクションをバインドし、DataTemplateで要素を見れるようにしたのですが、ListBoxで要素を変更した際にComboBoxの表示も変わってしまいます。

イメージ説明
左のListBoxで「hogehoge」を追記。すると右のComboBoxの文字列も反映される。
イメージ説明

挙動自体は私が想定していた通りなので問題は無いのですが、要素元のクラスのプロパティは全て自動プロパティで実装しており変更通知などがされません。
しかしどちらとも変更が反映されているため、なぜこの様な挙動になるか気になり質問を投稿させていただきました。

該当のソースコード

MainWindow.xaml

XAML

1<Window x:Class="My_Livet_Template_Project2.Views.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors" 5 xmlns:l="http://schemas.livet-mvvm.net/2011/wpf" 6 xmlns:v="clr-namespace:My_Livet_Template_Project2.Views" 7 xmlns:vm="clr-namespace:My_Livet_Template_Project2.ViewModels" 8 Title="MainWindow" Width="500" Height="350"> 9 10 <Window.DataContext> 11 <vm:MainWindowViewModel/> 12 </Window.DataContext> 13 14 <behaviors:Interaction.Triggers> 15 <behaviors:EventTrigger EventName="Loaded"> 16 <l:LivetCallMethodAction MethodName="Initialize" MethodTarget="{Binding}"/> 17 </behaviors:EventTrigger> 18 <behaviors:EventTrigger EventName="Closed"> 19 <l:DataContextDisposeAction/> 20 </behaviors:EventTrigger> 21 </behaviors:Interaction.Triggers> 22 23 <Grid> 24 <Grid.ColumnDefinitions> 25 <ColumnDefinition Width="1*"/> 26 <ColumnDefinition Width="1*"/> 27 </Grid.ColumnDefinitions> 28 29 <ListBox Name="listBox" ItemsSource="{Binding Settings}" HorizontalContentAlignment="Stretch"> 30 <ListBox.ItemTemplate> 31 <DataTemplate> 32 <StackPanel> 33 <TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" Margin="4"/> 34 <Slider Value="{Binding Item1}" Margin="4"/> 35 </StackPanel> 36 </DataTemplate> 37 </ListBox.ItemTemplate> 38 </ListBox> 39 40 <ComboBox ItemsSource="{Binding Settings}" SelectedIndex="0" VerticalAlignment="Top" Grid.Column="1" Margin="0,110,0,0"> 41 <ComboBox.ItemTemplate> 42 <DataTemplate> 43 <StackPanel> 44 <TextBlock Text="{Binding Name, StringFormat=Name: {0}}"/> 45 <TextBlock Text="{Binding Item1, StringFormat=Item1: {0}}"/> 46 </StackPanel> 47 </DataTemplate> 48 </ComboBox.ItemTemplate> 49 </ComboBox> 50 51 <Button Content="Button" HorizontalAlignment="Center" Margin="0,200,0,0" VerticalAlignment="Top" Grid.Column="1"> 52 <behaviors:Interaction.Triggers> 53 <behaviors:EventTrigger EventName="Click"> 54 <l:LivetCallMethodAction MethodName="AppendName" 55 MethodParameter="{Binding SelectedIndex, ElementName=listBox}" 56 MethodTarget="{Binding}"/> 57 </behaviors:EventTrigger> 58 </behaviors:Interaction.Triggers> 59 </Button> 60 </Grid> 61</Window> 62

MainWindowViewModel.cs

C#

1using Livet; 2using My_Livet_Template_Project2.Models; 3using System.Collections.ObjectModel; 4 5namespace My_Livet_Template_Project2.ViewModels 6{ 7 public class MainWindowViewModel : ViewModel 8 { 9 private ObservableCollection<Setting> _settings = new(); 10 11 public ObservableCollection<Setting> Settings 12 { 13 get => _settings; 14 set => RaisePropertyChangedIfSet(ref _settings, value); 15 } 16 17 public void Initialize() 18 { 19 Settings.Add(new()); 20 } 21 22 public void AppendName(int index) 23 { 24 if (index == -1) 25 return; 26 27 Settings[index].Name += "追記"; 28 } 29 } 30} 31

Setting.cs

C#

1namespace My_Livet_Template_Project2.Models 2{ 3 public class Setting 4 { 5 public string Name { get; set; } = "デフォルト"; 6 public int Item1 { get; set; } 7 8 //private string _name = "デフォルト"; 9 //public string Name 10 //{ 11 // get => _name; 12 // set => _name = value; 13 //} 14 } 15} 16

試したこと

  • ViewModel側で何か追記してみる(AppendName関数) → しっかり追記されているが、UI側では変わっていない
  • 要素クラスのプロパティを省略せずに書く(Setting.csにてコメントアウトしている部分) → 最初の挙動と同じ
  • SettingクラスにNotificationObjectを継承してみる → ComboBoxには反映されない

イメージ説明

  • SettingクラスにNotifcationObjectを継承し、プロパティで変更通知をする → 最初の挙動と同じ

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

Microsoft Visual Studio Community 2022 Version 17.5.2
C#10
LivetCask 4.0.2

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

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

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

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

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

unikuma

2023/03/21 13:54

回答ありがとうございます。PropertyDescriptorは初耳でした。 ここ最近はずっとこの挙動に悩まされていたのでとてもスッキリしました。ありがとうございます。
Zuishin

2023/03/21 21:21

自己解決してください。
unikuma

2023/03/22 03:38

すみません、忘れていました。 ご指摘ありがとうございます。
guest

回答1

0

自己解決

解決しました、PropertyDescriptorが原因だったみたいです。教えていただきありがとうございます。
また、こちらのページも参考になりました。
https://sakapon.wordpress.com/2016/07/17/databinding-console-4/
http://pro.art55.jp/?eid=1165021

投稿2023/03/22 03:37

unikuma

総合スコア11

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問