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

问题描述 投票:-1回答:2

我有一个网格,在那个网格里面有一个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)。无论如何,我想要的是,当我选中复选框时,释放的Stackpanel(panel1)的文本块值(name1name2name3的值)将传递给List(Of string),从中我可以获得堆栈面板中每个已检查的Checkboxes的三个文本块的值。 ..有点像DataGrid / DataGridView(winforms)..

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

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

c# wpf checkbox datagrid
2个回答
0
投票

非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>

在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;
        }
    }

0
投票

在使用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

© www.soinside.com 2019 - 2024. All rights reserved.