我有一个网格,在该网格内部有一个stackpanel
,里面有一个Checkbox
和2个TextBlocks
。 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(panel1)
的文本块值(name1
,name2
,name3
的值)将被传递给List(Of string)
我可以在其中获取stackpanels中每个已检查Checkboxes
的三个文本块的值...有点像DataGrid
/ DataGridView
(winforms).. < / p>
如果我没有正确描述我的需要,请原谅,但我希望你能理解我在寻找什么。我发现this但是由于我的动机和情况完全不同,我无法真正利用那篇文章中的答案......对我的想法有什么帮助/解释?
更新:更合理/更好的解释
如果我有UserControl
1 checkbox
和2 textblocks
并使用基于从数据表派生的数据行的usercontrol填充Window
的网格,我该如何获得已检查复选框的文本块值
UserControl
?
答案 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;
}
}