我知道你要求简单,但在某些时候你可以回到这个,因为它是一种非常结构化和可扩展的方式来保存和使用 WPF 中的数据
我会考虑以自己的结构量化这些类,每个类都有一个必须事先完成的先决条件类的列表,我建议使用以下内容来实现你所追求的(对不起,有点长!)
您将得到一个由复选框表示的类列表,您只能在其所有必备类都完成后检查一个类,它们具有名称和描述,并且可以在 UI 上以任何您想要的方式进行自定义。
创建一个新的 WPF 应用程序并添加以下类。类.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>