我正在尝试为我的大学的学位计划创建一个班级列表,在这里,当已经学习的班级被检查时,另一个班级会突出显示,让用户知道该班级已满足所有必备条件。所以如果我检查微积分1,物理1将会突出显示。
我是C#的新手,我不太了解语言和.NET框架可以做什么,所以我要求一个简单的直接答案,如果你能够准确地解释代码中发生的事情会很棒。感谢
到目前为止,这是我所拥有的。只是概念WPF的基本证明<Window x:Class="degree_plan.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Degree Planner" Height="350" Width="525" Name="Degree">
<Grid>
<CheckBox Content="Math 1412" Height="16" HorizontalAlignment="Left" Margin="34,40,0,0" Name="checkBox1" VerticalAlignment="Top" />
<CheckBox Content="Physics 1911" Height="16" HorizontalAlignment="Left" Margin="34,62,0,0" Name="checkBox2" VerticalAlignment="Top" />
</Grid>
</Window>
并且继承了c#代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace degree_plan
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// if (checkBox1.Checked)
// Console.WriteLine("physics 1");
}
}
}
答案 0 :(得分:1)
您可以为复选框注册事件处理程序:
AddHandler(CheckBox.CheckedEvent, new RoutedEventHandler(CheckBox_Click));
然后,创建事件处理程序:
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
CheckBox checkbox = e.Source as CheckBox
//...
}
事件处理程序中的checkbox
变量是单击以引发事件的复选框。您可以检查它是哪个复选框,然后启用所有依赖它的选项。
答案 1 :(得分:1)
我知道你要求的很简单,但在某些时候你可以回到这里,因为它是一种非常结构化和可扩展的方式来保存和使用WPF中的数据
我会考虑在他们自己的结构中量化Classes,每个都有一个必须事先完成的先决条件类的列表,我想建议使用以下来实现你所追求的目标(抱歉,有点长! )
您将获得的是一个由复选框表示的类列表,您只能在所有必备类完成后检查一个类,它们具有名称和描述,并且可以在UI上自定义您想要的任何内容。 / p>
创建一个新的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>
答案 2 :(得分:0)
为了您的方便, 尝试使用'CheckedChanged'事件..只需双击设计器上的CheckBox即可。处理程序将自动添加(类似,
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
}
。然后在那里添加你的代码。但是,这很耗时(因为,您必须为每个CheckBox添加处理程序)。但是,在这个阶段你很容易理解。