[英]Creating a dynamic checkbox list using C#
我正在嘗試為我的大學的學位計划創建一個班級列表,在這里,當已經學習的班級被檢查時,另一個班級會被突出顯示,讓用戶知道該班級已滿足所有必備條件。 所以如果我檢查微積分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");
}
}
}
您可以為復選框注冊事件處理程序:
AddHandler(CheckBox.CheckedEvent, new RoutedEventHandler(CheckBox_Click));
然后,創建事件處理程序:
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
CheckBox checkbox = e.Source as CheckBox
//...
}
事件處理程序中的checkbox
變量是單擊以引發事件的復選框。 您可以檢查它是哪個復選框,然后啟用所有依賴它的選項。
我知道你要求簡單,但在某些時候你可以回到這里,因為它是一種非常結構化和可擴展的方式來保存和使用WPF中的數據
我會考慮在他們自己的結構中量化Classes,每個都有一個必須事先完成的先決條件類的列表,我想建議使用以下來實現你所追求的目標(抱歉,有點長!)
你會得到的是一個由復選框表示的類列表,你只能在一個類完成所有必備類后檢查它們,它們有名稱和描述,並且可以在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>
為了方便起見,請嘗試使用'CheckedChanged'事件。只需雙擊設計器上的CheckBox即可。 處理程序將自動添加(類似於,
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
}
然后在那里添加你的代碼。 但是,這很耗時(因為,您必須為每個CheckBox添加處理程序)。 但是,在這個階段你很容易理解。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.