簡體   English   中英

使用C#創建動態復選框列表

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM