【问题标题】:Loop through checked checkboxes in grid and get lable values WPF c#循环遍历网格中的选中复选框并获取标签值 WPF c#
【发布时间】:2018-08-08 01:23:33
【问题描述】:

我有一个网格,在那个网格里面有一个stackpanel,里面有一个Checkbox和2个TextBlocksXAML 是:

  <Grid x:name="maingrid" >
    <Stackpanel x:name="panel1">
       <Checkbox height="10" width="10"/>
       <Textblock x:name="name1" text="a"/>
       <Textblock x:name="name2" text="b"/>
       <Textblock x:name="name3" text="c"/>
     </Stackpanel>
   </Grid>

现在,问题是,在MainGrid 中,我正在根据随机文本列表动态添加panel1(堆栈面板)。无论如何,我想要的是,当我选中复选框时,相关的 Stackpanel(panel1) 的文本块值(name1name2name3 的值)将被传递给 List(Of string) 从我可以获取堆栈面板中每个选中的Checkboxes 的三个文本块的值...有点像DataGrid/DataGridView (winforms) ..

如果我未能正确描述我的需求,请见谅,但我希望你能理解我在寻找什么。我找到了this,但由于我的动机和情况完全不同,我无法真正利用那篇文章中的答案......我的想法有什么帮助/解释吗?

更新:更合乎逻辑/更好的解释 如果我有一个 UserControl 和 1 checkbox 和 2 textblocks 并使用基于从数据表派生的数据行的用户控件填充 Window 的网格,我如何获取选中复选框的文本块值 UserControl?

【问题讨论】:

  • 问题不清楚。您编写了“动态添加”,但发布了包含堆栈面板的 XAML。你想在网格中插入StackPanels 的数量,还是永远只有一个?如果答案是“几个”,StackPanels 的内容是否相同,或者TextBlocks 的数量可以变化?用户可以勾选多个复选框吗?
  • 是的...我想在MianGrid 中添加多个堆栈面板,堆栈面板的内容将是相同的(1 个复选框和 2 个文本块),是的,用户可以检查多个 chekcboxes
  • 为什么不改用DataGridDataGrid+DataTable example
  • 我同意你的看法,但我昨天问了一个问题,关于如何从 access 数据库将数据绑定到 wpf 中的数据网格,但没有得到答案......所以我想自己制作一个......
  • @F.raiyan,你应该做一个更好的研究

标签: c# wpf checkbox datagrid


【解决方案1】:

非MVVM方式

在您的自定义用户控件中访问您的值。您需要一个 UserControl,其中的每个控件都有一个名称,然后在使用时,您只需调用它的名称。

在 MyUserControl.xaml 中:

<Stackpanel x:name="panel1">
   <Checkbox x:name="checkbox1" height="10" width="10"/> <!-- Apply your style here -->
   <Textblock x:name="name1" text="a"/>
   <Textblock x:name="name2" text="b"/>
   <Textblock x:name="name3" text="c"/>
</Stackpanel>

在 MyWindow.xaml 中:

<local:MyUserControl x:Name="myUserControlInstance"/>
<Button Content="Click me" Click="Button_Click" />

在 MyWindow.cs 中:

    private void Button_Click(object sender, RoutedEventArgs e) 
    {
        if (myUserControlInstance.checkbox1.IsChecked.HasValue)
        {
             var checkboxValue=myUserControlInstance.checkbox1.IsChecked.Value;
        }
    }

【讨论】:

  • 如果我有多个使用控件和多个选中的复选框,将能够循环通过它们吗?
  • 解决方案 1:您只需命名您添加的每个 UserControl 并循环访问该名称列表。解决方案 2:您需要在没有名称的情况下循环每个 UserControl。
  • 如何根据数据表中的数据行动态添加每个 usecontrol ?
【解决方案2】:

不要像使用 WinForms 一样尝试使用 XAML。这是一个死胡同。
首先使用 MVVM、数据绑定和处理数据。

这是“堆栈面板”及其内容的示例视图模型:

public sealed class ItemViewModel : ViewModelBase
{
    private bool isChecked;

    public bool IsChecked
    {
        get { return isChecked; }
        set
        {
            if (isChecked != value)
            {
                isChecked = value;
                OnPropertyChanged();
            }
        }
    }

    public string Name1 { get; set; }

    public string Name2 { get; set; }
}

ViewModelBase 是一个基本的INotifyPropertyChanged 实现(google it)。

接下来,查看示例应用程序的模型:

public sealed class MainViewModel
{
    private ObservableCollection<ItemViewModel> items;

    public ObservableCollection<ItemViewModel> Items
    {
        get
        {
            if (items == null)
            {
                items = new ObservableCollection<ItemViewModel>();
                items.CollectionChanged += ItemsCollectionChanged;
            }

            return items;
        }
    }

    private void ItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        switch (e.Action)
        {
            case NotifyCollectionChangedAction.Add:
                // we want to be notified, if IsChecked is changed;
                // ObservableCollection<T> adds one item per time, so, we just using NewItems[0]
                ((ItemViewModel)e.NewItems[0]).PropertyChanged += ItemPropertyChanged;
                break;
            case NotifyCollectionChangedAction.Remove:
                // we need to unsibscribe, when removing item from collection,
                // to avoid memory leak
                ((ItemViewModel)e.OldItems[0]).PropertyChanged -= ItemPropertyChanged;
                break;
        }
    }

    private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        // we're interested only in IsCheckedProperty
        if (e.PropertyName == nameof(ItemViewModel.IsChecked))
        {
            // let's update our list
            UpdateItemTextValues();
        }
    }

    private void UpdateItemTextValues()
    {
        // retrieving NameN property values from checked items as a single list
        var itemTextValues = Items
            .Where(_ => _.IsChecked)
            .Select(_ => new[]
            {
                _.Name1,
                _.Name2
            })
            .SelectMany(_ => _)
            .ToList();

        // do somethig with the list
        Trace.WriteLine(null);

        foreach (var value in itemTextValues)
        {
            Trace.WriteLine(value);
        }
    }
}

XAML。请注意,您不需要Grid,请改用ItemsControl

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <ItemsControl ItemsSource="{Binding Items}">
        <ItemsControl.ItemTemplate>
            <DataTemplate DataType="{x:Type local:ItemViewModel}">
                <StackPanel>
                    <CheckBox Content="Check me" IsChecked="{Binding IsChecked}"/>
                    <TextBlock Text="{Binding Name1}"/>
                    <TextBlock Text="{Binding Name2}"/>
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Window>

MainWindow 的代码隐藏:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        DataContext = new MainViewModel
        {
            Items =
            {
                // these are samle items;
                // you can fill collection the way you want
                new ItemViewModel { Name1 = "A", Name2 = "B" },
                new ItemViewModel { Name1 = "C", Name2 = "D" },
                new ItemViewModel { Name1 = "E", Name2 = "F" },
            }
        };
    }
}

如果是UserControl,您必须从您的控件中提供适当的属性以绑定到ItemTemplate,并更改ItemTemplate

【讨论】:

  • 我对 MVVM 几乎一无所知,所以一个基本的问题:我需要为此创建一个新项目吗?我该如何真正开始?
  • 我找到了this,我开始学习MVVM...在了解了基础知识之后,我会实现你的结果
  • 您可以将此代码复制/粘贴到新的 WpfApplication 项目并使用它。事实上,我也是这样做的。不要害怕 MVVM - 它并不难学。
  • 我可以在现有项目中使用它吗?
  • 当然可以。但是您需要根据当前代码对其进行调整。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 2013-04-19
  • 1970-01-01
  • 2017-12-01
相关资源
最近更新 更多