循环检查网格中的复选框,并获取标签值WPF c#

循环检查网格中的复选框,并获取标签值WPF c#,c#,wpf,checkbox,datagrid,C#,Wpf,Checkbox,Datagrid,我有一个网格,网格内有一个堆栈面板,其中有一个复选框和两个文本块。XAML是: <Grid x:name="maingrid" > <Stackpanel x:name="panel1"> <Checkbox height="10" width="10"/> <Textblock x:name="name1" text="a"/> <Textblock x:name="name2" tex

我有一个网格,网格内有一个
堆栈面板
,其中有一个
复选框
和两个
文本块
XAML
是:

  <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)。无论如何,我想要的是,当我选中复选框时,releavent
Stackpanel(panel1)
的文本块值(
name1
name2
name3
的值)将被传递到
列表(字符串)
,从中我可以获得stackpanels中每个选中的
复选框的三个文本块的值。。。有点像
DataGrid
/
DataGridView
(winforms)

如果我没有正确描述我的需求,请原谅,但我希望你能理解我在寻找什么。我发现,但由于我的动机和处境完全不同,我无法真正利用那篇文章中的答案。。。对我的想法有什么帮助/解释吗

更新:更符合逻辑/更好的解释 如果我有一个
UserControl
,带有1个
复选框和2个
textblocks
,并基于从数据表派生的数据行使用UserControl填充
窗口的网格,我如何获得

UserControl

不要像使用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);
        }
    }
}
main窗口的代码隐藏:

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

非MVVM方式

访问自定义UserControl中的值。您需要一个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>

问题还不清楚。您编写了“动态添加”,但发布了包含堆栈面板的XAML。是否要在网格中插入
StackPanel
s的编号,还是始终只有一个?如果答案是“多个”,则
StackPanel
s的内容是否相同,或者
TextBlock
s的数量可能不同?用户是否可以选中多个复选框?是的……我想在
MianGrid
中添加多个stackpanels,stackpanels内容将相同(1个复选框和2个文本块),是的,用户可以选中多个复选框为什么不使用
DataGrid
?我同意你的看法,但我昨天问了一个问题,关于如何从access数据库将数据绑定到wpf中的datagrid,但没有得到答案…所以我想自己做一个…@F.raiyan,你应该做得更好我对MVVM几乎一无所知,所以一个基本的问题是:我需要为此创建一个新项目吗?我如何真正开始呢?我发现并开始学习MVVM…了解基本知识后,我将实现您的结果您可以将此代码复制/粘贴到新的WPFAApplication项目并使用它。事实上,我也这么做了。不要害怕MVVM——它并不难学。我可以在现有的项目中使用它吗?当然可以。但您需要根据当前代码对其进行调整。如果我有多个UseControl和多个复选框,您是否能够循环使用它们?解决方案1:您只需要命名您添加的每个UserControl,并循环使用该名称列表。解决方案2:您需要在每个UserControl上循环,而不使用它的名称。在基于datatable中的datarows动态添加usecontrol时,如何命名每个usecontrol?
<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>
<local:MyUserControl x:Name="myUserControlInstance"/>
<Button Content="Click me" Click="Button_Click" />
    private void Button_Click(object sender, RoutedEventArgs e) 
    {
        if (myUserControlInstance.checkbox1.IsChecked.HasValue)
        {
             var checkboxValue=myUserControlInstance.checkbox1.IsChecked.Value;
        }
    }