シンプルを求められたことは知っていますが、WPF でデータを保持および使用するための非常に構造化された拡張可能な方法であるため、ある時点でこれに戻ることができます。
独自の構造でクラスを定量化することを検討します。それぞれに、事前に完了する必要がある前提条件クラスのリストがあります。次を使用して、目的を達成することをお勧めします (申し訳ありませんが、少し長くなります!)
取得されるのは、チェックボックスで表されるクラスのリストです。必要なクラスがすべて完了した場合にのみ、クラスをチェックできます。クラスには名前と説明があり、必要に応じて UI でカスタマイズできます。
新しい WPF アプリケーションを作成し、次のクラスを追加します。Class.cs
public class Class : Control, INotifyPropertyChanged
{
// Property that's raised to let other clases know when a property has changed.
public event PropertyChangedEventHandler PropertyChanged;
// Flags to show what's going on with this class.
bool isClassComplete;
bool isPreComplete;
// Some other info about the class.
public string ClassName { get; set; }
public string Description { get; set; }
// A list of prerequisite classes to this one.
List<Class> prerequisites;
// public property access to the complete class, you can only set it to true
// if the prerequisite classes are all complete.
public bool IsClassComplete
{
get { return isClassComplete; }
set
{
if (isPreComplete)
isClassComplete = value;
else
if (value)
throw new Exception("Class can't be complete, pre isn't complete");
else
isClassComplete = value;
PropertyChangedEventHandler temp = PropertyChanged;
if (temp != null)
temp(this, new PropertyChangedEventArgs("IsClassComplete"));
}
}
// public readonly property access to the complete flag.
public bool IsPreComplete { get { return isPreComplete; } }
public Class()
{
prerequisites = new List<Class>();
isPreComplete = true;
}
// adds a class to the prerequisites list.
public void AddPre(Class preClass)
{
prerequisites.Add(preClass);
preClass.PropertyChanged += new PropertyChangedEventHandler(preClass_PropertyChanged);
ValidatePre();
}
// removes a class from the prerequisites lists.
public void RemovePre(Class preClass)
{
prerequisites.Remove(preClass);
preClass.PropertyChanged -= new PropertyChangedEventHandler(preClass_PropertyChanged);
ValidatePre();
}
// each time a property changes on one of the prerequisite classes this is run.
void preClass_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "IsClassComplete":
// check to see if all prerequisite classes are complete/
ValidatePre();
break;
}
}
void ValidatePre()
{
if (prerequisites.Count > 0)
{
bool prerequisitesComplete = true;
for (int i = 0; i < prerequisites.Count; i++)
prerequisitesComplete &= prerequisites[i].isClassComplete;
isPreComplete = prerequisitesComplete;
if (!isPreComplete)
IsClassComplete = false;
}
else
isPreComplete = true;
PropertyChangedEventHandler temp = PropertyChanged;
if (temp != null)
temp(this, new PropertyChangedEventArgs("IsPreComplete"));
}
}
MainWindow.cs のコード ビハインドでは、クラスのコレクションを作成できます。コンストラクターでこれを行い、監視可能なクラスのコレクションを提供したので、新しいクラスが追加されたときに、それらを取得するために何もする必要はありません。 UIに表示する
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public ObservableCollection<Class> Classes
{
get { return (ObservableCollection<Class>)GetValue(ClassesProperty); }
set { SetValue(ClassesProperty, value); }
}
public static readonly DependencyProperty ClassesProperty = DependencyProperty.Register("Classes", typeof(ObservableCollection<Class>), typeof(MainWindow), new UIPropertyMetadata(null));
public MainWindow()
{
InitializeComponent();
Class math = new Class()
{
ClassName = "Math 1412",
Description = ""
};
Class physics = new Class()
{
ClassName = "Physics 1911",
Description = "Everything everywhere anywhen",
};
physics.AddPre(math);
Classes = new ObservableCollection<Class>();
Classes.Add(math);
Classes.Add(physics);
}
}
最後の手順は、クラスがユーザー インターフェイス上でどのように表示されるかを WPF に伝えることです。これはリソースで行われ、例を簡略化するために MainWindow.xaml ファイルに入れました。
<Window x:Class="WpfApplication8.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication8"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<!-- This tells WPF what a class looks like -->
<Style TargetType="{x:Type local:Class}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:Class}">
<StackPanel Orientation="Horizontal" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">
<!-- Checkbox and a text label. -->
<CheckBox IsEnabled="{Binding IsPreComplete}" IsChecked="{Binding IsClassComplete}" />
<TextBlock Margin="5,0,0,0" Text="{Binding ClassName}" ToolTip="{Binding Description}"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<!-- This draws the list of classes from the property in MainWindow.cs-->
<ItemsControl ItemsSource="{Binding Classes}"/>
</Grid>
</Window>