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

时间:2018-02-28 08:19:32

标签: c# wpf checkbox datagrid

我有一个网格,在该网格内部有一个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)我可以在其中获取stackpanels中每个已检查Checkboxes的三个文本块的值...有点像DataGrid / DataGridView(winforms).. < / p> 如果我没有正确描述我的需要,请原谅,但我希望你能理解我在寻找什么。我发现this但是由于我的动机和情况完全不同,我无法真正利用那篇文章中的答案......对我的想法有什么帮助/解释?

更新:更合理/更好的解释 如果我有UserControl 1 checkbox和2 textblocks并使用基于从数据表派生的数据行的usercontrol填充Window的网格,我该如何获得已检查复选框的文本块值 UserControl

2 个答案:

答案 0 :(得分:0)

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

此处&#34;堆叠面板&#34;及其内容的示例视图模型:

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

答案 1 :(得分: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;
        }
    }