ObservableCollection

ObservableCollection は要素の追加・削除に関する変更は監視しますが、コレクション内の要素のプロパティが変更された場合には自動で再描画はされません。要素のプロパティが変更された場合にも自動的に再描画されるようにするには、コレクション内の各要素に**INotifyPropertyChanged インターフェイス**を実装する必要があります。

INotifyPropertyChanged を使った再描画の実現方法

  1. UserControl のデータモデルクラスに INotifyPropertyChanged を実装
  2. プロパティが変更されると通知が発生し、UIが再描画

以下に例を示します。

1. データモデルクラスの作成

まず、UserControl の中身に表示されるデータを持つモデルクラス UserControlData を作成し、INotifyPropertyChanged を実装します。

using System.ComponentModel;

namespace YourNamespace
{
public class UserControlData : INotifyPropertyChanged
{
private string _displayText;

public string DisplayText
{
get => _displayText;
set
{
if (_displayText != value)
{
_displayText = value;
OnPropertyChanged(nameof(DisplayText));
}
}
}

public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

2. UserControl のバインディング設定

次に、UserControlTextBlock などの表示要素を、UserControlDataDisplayText プロパティにバインドします。

SampleUserControl.xaml

<UserControl x:Class="YourNamespace.SampleUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<TextBlock Text="{Binding DisplayText}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="20"/>
</Grid>
</UserControl>

SampleUserControl.xaml.cs

SampleUserControl のコードビハインドで、UserControlData をデータコンテキストとして設定します。

using System.Windows.Controls;

namespace YourNamespace
{
public partial class SampleUserControl : UserControl
{
public SampleUserControl(UserControlData data)
{
InitializeComponent();
DataContext = data;
}
}
}

3. MainWindow での使用

MainWindowOnAddUserControlClick メソッドを修正し、UserControlData のインスタンスを使って SampleUserControl を作成し、UserControlCollection に追加します。

using System;
using System.Collections.ObjectModel;
using System.Windows;

namespace YourNamespace
{
public partial class MainWindow : Window
{
private readonly ObservableCollection<UserControl> UserControlCollection;
private int currentIndex = 0;

public MainWindow()
{
InitializeComponent();
UserControlCollection = new ObservableCollection<UserControl>();
}

private void OnAddUserControlClick(object sender, RoutedEventArgs e)
{
if (currentIndex < userControlTypes.Length)
{
// 新しい UserControlData を作成
var data = new UserControlData { DisplayText = $"Control {currentIndex + 1}" };
var control = new SampleUserControl(data);

UserControlCollection.Add(control);
currentIndex++;
}
}

// 任意のメソッドで UserControlData のプロパティを更新
private void UpdateUserControlText(int index, string newText)
{
if (index >= 0 && index < UserControlCollection.Count)
{
// UserControl を取り出し、DataContext の DisplayText プロパティを更新
var control = UserControlCollection[index] as SampleUserControl;
var data = control?.DataContext as UserControlData;
if (data != null)
{
data.DisplayText = newText;
}
}
}
}
}

説明

  • INotifyPropertyChanged の実装UserControlData クラスは INotifyPropertyChanged を実装しており、DisplayText プロパティの値が変更されると PropertyChanged イベントが発生します。これにより、バインドされている UI 要素が自動的に更新されます。

  • UpdateUserControlText メソッドでのデータ更新UpdateUserControlText メソッドを呼び出し、特定の UserControlDataDisplayText プロパティを更新することで、UI が再描画されます。

  • バインディングの動作SampleUserControlTextBlockDisplayText プロパティにバインドされているため、DisplayText の値が変更されると自動的に再描画が行われ、UI に反映されます。

コメント

タイトルとURLをコピーしました