我有一个由字符串和数组组成的对象。字符串填充ComboBox
,数组填充ListView
,这取决于所选的字符串值。ListView
的每一行都由TextBlock
和CheckBox
组成。
在提交时,我希望能够验证哪些项已被选中进行进一步处理,但在使用MVVM方法时会出现中断。我目前将提交Button
的DataContext
绑定到ListView
,但在提交时只返回第一个值(我需要将选定的值保存到一个列表中,我假设是这样,但我不确定保存在哪里)。我向模型添加了一个IsSelected
属性,我认为这是第一步,但之后我一直在抓救命稻草。
型号
namespace DataBinding_WPF.Model
{
public class ExampleModel { }
public class Example : INotifyPropertyChanged
{
private string _name;
private string[] _ids;
private bool _isSelected;
public bool IsSelected
{
get => _isSelected;
set
{
if (_isSelected != value)
{
_isSelected = value;
RaisePropertyChanged("IsSelected");
}
}
}
public string Name
{
get => _name;
set
{
if (_name != value)
{
_name = value;
RaisePropertyChanged("Name");
}
}
}
public string[] IDs
{
get => _ids;
set
{
if (_ids != value)
{
_ids = value;
RaisePropertyChanged("IDs");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new
PropertyChangedEventArgs(property));
}
}
}
}
检视模型
namespace DataBinding_WPF.ViewModel
{
public class ExampleViewModel : INotifyPropertyChanged
{
public ObservableCollection<Example> Examples
{
get;
set;
}
// SelectedItem in the ComboBox
// SelectedItem.Ids will be ItemsSource for the ListBox
private Example _selectedItem;
public Example SelectedItem
{
get => _selectedItem;
set
{
_selectedItem = value;
RaisePropertyChanged(nameof(SelectedItem));
}
}
// SelectedId in ListView
private string _selectedId;
public string SelectedId
{
get => _selectedId;
set
{
_selectedId = value;
RaisePropertyChanged(nameof(SelectedId));
}
}
private string _selectedCheckBox;
public string IsSelected
{
get => _selectedCheckBox;
set
{
_selectedCheckBox = value;
RaisePropertyChanged(nameof(IsSelected));
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new
PropertyChangedEventArgs(property));
}
}
public void LoadExample()
{
ObservableCollection<Example> examples = new ObservableCollection<Example>();
examples.Add(new Example { Name = "Mark", IDs = new string[] { "123", "456" }, IsSelected = false });
examples.Add(new Example { Name = "Sally", IDs = new string[] { "789", "101112" }, IsSelected = false });
Examples = examples;
}
/* BELOW IS A SNIPPET I ADDED FROM AN EXAMPLE I FOUND ONLINE BUT NOT SURE IF IT'S NEEDED */
private ObservableCollection<Example> _bindCheckBox;
public ObservableCollection<Example> BindingCheckBox
{
get => _bindCheckBox;
set
{
_bindCheckBox = value;
RaisePropertyChanged("BindingCheckBox");
}
}
}
}
检视
<UserControl x:Class = "DataBinding_WPF.Views.StudentView"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:local = "clr-namespace:DataBinding_WPF"
mc:Ignorable = "d"
d:DesignHeight = "300" d:DesignWidth = "300">
<Grid>
<StackPanel HorizontalAlignment = "Left" >
<ComboBox HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="120"
ItemsSource="{Binding Path=Examples}"
SelectedItem="{Binding SelectedItem}"
DisplayMemberPath="Name"/>
<ListView x:Name="myListView"
ItemsSource="{Binding SelectedItem.IDs}"
DataContext="{Binding DataContext, ElementName=submit_btn}"
SelectedItem="{Binding SelectedId}"
Height="200" Margin="10,50,0,0"
Width="Auto"
VerticalAlignment="Top"
Background="AliceBlue">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<CheckBox
Name="myCheckBox"
IsChecked="{Binding IsSelected,
RelativeSource={RelativeSource AncestorType=ListViewItem}}"
Margin="5, 0"/>
<TextBlock Text="{Binding}" FontWeight="Bold" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button HorizontalAlignment="Left" Height="20" Width="100"
Click="Submit" x:Name="submit_btn">Submit</Button>
</StackPanel>
</Grid>
</UserControl>
View.cs
namespace DataBinding_WPF.Views
{
/// <summary>
/// Interaction logic for StudentView.xaml
/// </summary>
public partial class StudentView : UserControl
{
public StudentView()
{
InitializeComponent();
}
private void Submit(object sender, EventArgs e)
{
var selectedItems = ((Button)sender).DataContext;
// process each selected item
// foreach (var selected in ....) { }
}
}
}
2条答案
按热度按时间0kjbasz61#
ListView
控件已将选定项集合公开为属性SelectedItems
。但是,我怀疑您是否希望在代码隐藏中执行此操作,而是希望在视图模型中执行此操作。
您需要的是中继命令或委派命令(名称因框架而异)。它封装了一个应该执行的方法(例如,单击按钮)和一个确定命令是否可以作为可以绑定到视图中的对象执行的方法。遗憾的是,WPF没有提供现成的实现,因此您要么必须复制here之类的实现,要么使用已经提供了一个实现的MVVM框架,例如Microsoft MVVM Tookit。
您可以在
ExampleViewModel
中公开ICommand
型别的属性Submit
,并在建构函式中以委派给要执行之方法的RelayCommand<T>
执行严修初始化它。在您的视图中,可以删除
Click
事件处理程序,并将Submit
属性绑定到Button
的Command
属性。还可以将ListView
的SelectedItems
属性绑定到CommandParameter
属性,以便在执行时将选定项传递给命令。此外,还有一些关于XAML的说明。
ListView
中完全删除DataContext
绑定,因为它无论如何都会自动接收与Button
相同的数据上下文。ExampleViewModel
中公开和绑定SelectedItem
属性。txu3uszq2#
如果视图的数据上下文绑定到视图,则从ListView中删除DataContext。
您可以移除项目模板,并改用GridView,例如:
由于ItemSource是一个可观察的集合,因此在复选框中有几个用于监视更改的选项:
1.将事件处理程序添加到集合的item changed事件,然后可以将Name或集合索引添加到本地集合。例如Examples[e.CollectionIndex].Name
1.或者,迭代可观察集合并选择Selected =“true”的那些示例