如何在 MVVM-WPF 中获取所选项目
Posted
技术标签:
【中文标题】如何在 MVVM-WPF 中获取所选项目【英文标题】:How to get selected item in MVVM-WPF 【发布时间】:2013-08-29 23:49:29 【问题描述】:您好,我正在使用 WPF 和 MVVM,我的应用程序中有“编辑/更新”面板,它会更新 Grid 中的选定数据。它工作正常。我想添加一个按钮“关闭按钮”和“一个检查用户是否选择了项目。如果他没有选择任何项目并单击“编辑按钮”,它将向用户显示一个消息框以选择一个项目编辑。我不清楚的是如何通过“选定的项目来做这两件事”并在关闭面板之前检查文本框字段中是否有任何文本。 用户查看模型代码:
public class UserViewModel
private IList<User> _UsersList;
public UserViewModel()
_UsersList = new List<User>
new User UserId = 1, FirstName = "Raj", LastName = "Beniwal", City = "Delhi", State = "DEL", Country = "INDIA" ,
new User UserId = 2, FirstName = "Mark", LastName = "henry", City = "New York", State = "NY", Country = "USA" ,
new User UserId = 3, FirstName = "Mahesh", LastName = "Chand", City = "Philadelphia", State = "PHL", Country = "USA" ,
new User UserId = 4, FirstName = "Vikash", LastName = "Nanda", City = "Noida", State = "UP", Country = "INDIA" ,
new User UserId = 5, FirstName = "Harsh", LastName = "Kumar", City = "Ghaziabad", State = "UP", Country = "INDIA" ,
new User UserId = 6, FirstName = "Reetesh", LastName = "Tomar", City = "Mumbai", State = "MP", Country = "INDIA" ,
new User UserId = 7, FirstName = "Deven", LastName = "Verma", City = "Palwal", State = "HP", Country = "INDIA" ,
new User UserId = 8, FirstName = "Ravi", LastName = "Taneja", City = "Delhi", State = "DEL", Country = "INDIA"
;
public IList<User> Users
get return _UsersList;
set _UsersList = value;
private ICommand mUpdater;
public ICommand UpdateCommand
get
if (mUpdater == null)
mUpdater = new Updater();
return mUpdater;
set
mUpdater = value;
private class Updater : ICommand
#region ICommand Members
public bool CanExecute(object parameter)
return true;
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
#endregion
用户视图窗口.Xaml 面板 1
<dxdo:LayoutPanel Caption="Panel1" x:Name="Panel1">
<Grid Margin="0,0,0,20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListView Name="UserGrid" Grid.Row="1" Margin="4,178,12,13" ItemsSource="Binding Users">
<ListView.View>
<GridView x:Name="grdTest">
<GridViewColumn Header="UserId" DisplayMemberBinding="Binding UserId" Width="50" />
<GridViewColumn Header="First Name" DisplayMemberBinding="Binding FirstName" Width="80" />
<GridViewColumn Header="Last Name" DisplayMemberBinding="Binding LastName" Width="100" />
<GridViewColumn Header="City" DisplayMemberBinding="Binding City" Width="80" />
<GridViewColumn Header="State" DisplayMemberBinding="Binding State" Width="80" />
<GridViewColumn Header="Country" DisplayMemberBinding="Binding Country" Width="100" />
</GridView>
</ListView.View>
</ListView>
</Grid>
</dxdo:LayoutPanel>
<dxdo:LayoutPanel x:Name="Panel3">
<Grid>
<StackPanel>
<Button Content="Edit" Height="23" HorizontalAlignment="Left" VerticalAlignment="Top" Width="141" Click="Button_Click_1" />
</StackPanel>
</Grid>
</dxdo:LayoutPanel>
面板 2:
<dxdo:LayoutPanel Caption="Panel2" x:Name="Panel2">
<Grid>
<StackPanel Margin="0,0,0,10">
<Grid Margin="0,0,0,20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,7,0,0" Name="txtUserId" VerticalAlignment="Top" Width="178" Text="Binding ElementName=UserGrid, Path=SelectedItem.UserId" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,35,0,0" Name="txtFirstName" VerticalAlignment="Top" Width="178" Text="Binding ElementName=UserGrid, Path=SelectedItem.FirstName" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,62,0,0" Name="txtLastName" VerticalAlignment="Top" Width="178" Text="Binding ElementName=UserGrid, Path=SelectedItem.LastName" />
<Label Content="UserId" Grid.Row="1" HorizontalAlignment="Left" Margin="12,12,0,274" Name="label1" />
<Label Content="Last Name" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,60,0,0" Name="label2" VerticalAlignment="Top" />
<Label Content="First Name" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,35,0,0" Name="label3" VerticalAlignment="Top" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,143,0,0" x:Name="txtCity" VerticalAlignment="Top" Width="178" Text="Binding SelectedItem.City, ElementName=UserGrid" />
<Label Content="Country" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,141,0,0" x:Name="label2_Copy" VerticalAlignment="Top" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,88,0,0" x:Name="txtCountry" VerticalAlignment="Top" Width="178" Text="Binding SelectedItem.Country, ElementName=UserGrid" />
<Label Content="City" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,86,0,0" x:Name="label2_Copy1" VerticalAlignment="Top" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,115,0,0" x:Name="txtSTate" VerticalAlignment="Top" Width="178" Text="Binding SelectedItem.State, ElementName=UserGrid" />
<Label Content="State" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,113,0,0" x:Name="label2_Copy2" VerticalAlignment="Top" />
</Grid>
<Button Content="Update" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="310,40,0,0" Name="btnUpdate" VerticalAlignment="Top" Width="141" Command="Binding Path=UpdateCommad" />
<Button Content="Close" Grid.Row="1" Height="23" HorizontalAlignment="Right" VerticalAlignment="Top" Width="141" Click="Button_Click_2" />
<TextBox Width="166" Background="White" Height="33" HorizontalAlignment="Right" VerticalAlignment="Bottom" Text="Binding Path=SelectedCustomer.LastName,Mode=OneWay,UpdateSourceTrigger=PropertyChanged" />
</StackPanel>
</Grid>
</dxdo:LayoutPanel>
(如果我的问题你不清楚,请问我。谢谢)
【问题讨论】:
在用户选择要执行此操作的项目之前,您的编辑按钮不应该是 aktiv,您可以使用 RelayCommandsButton_Click_1
, Button_Click_2
- 这不是 MVVM。
也看看this question
【参考方案1】:
在 ViewModel 中创建一个属性来保存选定的用户:
public User SelectedUser get; set;
将 ListView 的 SelectedItem 绑定到该属性:
<ListView Name="UserGrid" ItemsSource="Binding Users" SelectedItem="Binding SelectedUser">
现在您只需检查SelectedUser
属性是否为空。
【讨论】:
如何判断是否为空?在哪里定义这个? If(SelectedUser == null) ShowNoUserSelectedWarning(); 编译器说 SelectedUser 它是属性但使用类似变量。【参考方案2】:如何通过“选中的项目来做这两件事”
这通常可以通过视图模型中的SelectedSomething
属性来实现。此属性应绑定到控件的SelectedItem
。
并在关闭面板之前检查文本框字段中是否有任何文本
这称为“验证”。 WPF 以多种方式支持验证,其中之一是在您的视图模型中实现IDataErrorInfo
。我推荐这种方式,因为它是 .NET 的事实上的标准(它也用于 WinForms 和 ASP .NET)。
检查用户是否选择了项目。如果他没有选择任何项目并单击“编辑按钮”,它将向用户显示一个消息框以选择要编辑的项目
同样,这通常是通过绑定到按钮的ICommand
实例来解决的。如果ICommand.CanExecute
返回 false,绑定按钮将被禁用。
例如,您应该检查CanExecute
for command,绑定到Close
按钮的验证错误,如果有任何错误,则返回false。或者您应该检查CanExecute
中的SelectedSomething
属性以获取命令,绑定到Edit
按钮,如果SelectedSomething == null
则返回false
。
在 MVVM 世界中,如果您使用 RelayCommand
/DelegateCommand
作为默认的 ICommand
实现,事情会变得更容易。
更新。
命令的代码示例。 查看模型:
public class UserViewModel
public UserViewModel()
EditCommand = new RelayCommand(EditSelectedUser, () => SelectedUser != null);
private void EditSelectedUser()
// some edit code here
public User SelectedUser get; set;
public ICommand EditCommand get; private set;
XAML:
<Button Content="Edit" Command="Binding EditCommand"/>
【讨论】:
如果您不想在视图模型中保留 SelectedItem 属性,您也可以将所选项目作为参数传递给命令。您也可以使用相同的命令发出警告,如果未选择任何内容,即传递的参数为空,并且如果参数不为空,则进一步处理。 @Dennis 感谢您的回复。如何实现这个Again, usually, this being solved with ICommand instance, bound to the button. If ICommand.CanExecute returns false, bound button becomes disabled
你能通过代码描述一下吗?以上是关于如何在 MVVM-WPF 中获取所选项目的主要内容,如果未能解决你的问题,请参考以下文章
如何在recyclerview中获取所选项目,何时在片段内?
如何从 QComboBox 中获取所选项目以显示在 PyQt5 的 QTableWidget 中? (QComboBox 有复选框来选择项目)