@mikehc によって提案されたアプローチがどのように機能するかを説明するために、次の実際のコード サンプルを見てください。
FeedViewModel.cs - 子の同期ステータスからの情報を使用して、タイトルの定期的な更新 (このコードで 1 秒、または好きな/必要なもの) にタイマーを使用していることに注意してください。これは、各子からのイベントをサブスクライブして、同期されるときに通知を受けたり、新しい子アイテムの追加や古い子アイテムの削除などを処理したりするよりも、はるかに簡単なソリューションです。
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows.Threading;
namespace WpfApplication11
{
public class FeedViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate {};
DispatcherTimer timer =
new DispatcherTimer(DispatcherPriority.Background);
private string feedName;
public string FeedName
{
get { return feedName; }
set
{
feedName = value;
PropertyChanged(this,
new PropertyChangedEventArgs("FeedName"));
PropertyChanged(this,
new PropertyChangedEventArgs("FeedTitle"));
}
}
public ObservableCollection<ItemViewModel> FeedItems { get; set; }
public string FeedTitle
{
get
{
return string.Format("({0}/{1}) {2}",
FeedItems.Count(item => item.IsSynchronized),
FeedItems.Count,
FeedName);
}
}
public FeedViewModel()
{
FeedItems = new ObservableCollection<ItemViewModel>();
timer.Interval = TimeSpan.FromMilliseconds(1000);
timer.Tick += (sender, args) =>
PropertyChanged(this,
new PropertyChangedEventArgs("FeedTitle"));
timer.Start();
}
}
}
ItemViewModel.cs :
using System.ComponentModel;
namespace WpfApplication11
{
public class ItemViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate {};
private string itemName;
private bool isSynchronized;
public string ItemName
{
get { return itemName; }
set
{
itemName = value;
PropertyChanged(this, new PropertyChangedEventArgs("ItemName"));
}
}
public bool IsSynchronized
{
get { return isSynchronized; }
set
{
isSynchronized = value;
PropertyChanged(this,
new PropertyChangedEventArgs("IsSynchronized"));
}
}
}
}
DataSetCreator.cs - これは、コードで言及したクラスのDataSetとDataSetCreatorの 2 つのモックに過ぎないため、独自のものを自由に使用してください):
using System.Collections.ObjectModel;
namespace WpfApplication11
{
public class DataSet
{
public ObservableCollection<FeedViewModel> Feeds { get; private set; }
public DataSet()
{
Feeds = new ObservableCollection<FeedViewModel>
{
new FeedViewModel
{
FeedName = "Feed #1",
FeedItems = new ObservableCollection<ItemViewModel>
{
new ItemViewModel
{
ItemName = "Item #1.1",
IsSynchronized = true
},
new ItemViewModel
{
ItemName = "Item #1.2",
IsSynchronized = true
},
new ItemViewModel
{
ItemName = "Item #1.3",
IsSynchronized = false
},
}
},
new FeedViewModel
{
FeedName = "Feed #2",
FeedItems = new ObservableCollection<ItemViewModel>
{
new ItemViewModel
{
ItemName = "Item #2.1",
IsSynchronized = true
},
new ItemViewModel
{
ItemName = "Item #2.2",
IsSynchronized = true
},
}
},
new FeedViewModel
{
FeedName = "Feed #3",
FeedItems = new ObservableCollection<ItemViewModel>
{
new ItemViewModel
{
ItemName = "Item #3.1",
IsSynchronized = false
},
new ItemViewModel
{
ItemName = "Item #3.2",
IsSynchronized = false
},
}
}
};
}
}
public class DataSetCreator
{
public DataSet CreateDataSet()
{
return new DataSet();
}
}
}
最後に、MainWindow.xaml -上記のモック クラスDataSetCreator.csを使用するように更新します。
<Window x:Class="WpfApplication11.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication11"
mc:Ignorable="d" Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:ItemViewModel x:Key="DesignItemViewModel" />
<local:FeedViewModel x:Key="DesignFeedViewModel" />
<ObjectDataProvider x:Key="dataSetProvider"
ObjectType="{x:Type local:DataSetCreator}"
MethodName="CreateDataSet" />
<DataTemplate x:Key="ItemTemplate">
<StackPanel Orientation="Horizontal"
d:DataContext="{StaticResource DesignItemViewModel}">
<TextBlock Text="{Binding Path=ItemName}" />
<CheckBox IsChecked="{Binding Path=IsSynchronized}"
Margin="25,0,0,0"
Content=" is synchronized?"/>
</StackPanel>
</DataTemplate>
<HierarchicalDataTemplate x:Key="FeedTemplate"
ItemsSource="{Binding Path=FeedItems}"
ItemTemplate="{StaticResource ItemTemplate}">
<StackPanel Orientation="Horizontal"
d:DataContext="{StaticResource DesignFeedViewModel}">
<TextBlock Text="{Binding Path=FeedTitle}" />
</StackPanel>
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<TreeView DataContext="{StaticResource dataSetProvider}"
d:DataContext="{StaticResource dataSetProvider}"
ItemsSource="{Binding Path=Feeds}"
ItemTemplate="{StaticResource FeedTemplate}" />
</Grid>
</Window>