C# 如何在 MVVM-WPF 中获取所选项目
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18461914/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get selected item in MVVM-WPF
提问by Zoya Sheikh
Hi I am using WPF and MVVM, There is "Edit/Update" Panel in my application it updates selected data in Grid. It is working fine. I want to add one button "Close Button" and "one check to see whether user has selected item or not. If he doesn't select any item and click on "Edit Button" It will show a MessageBox to user to select an item to edit. Thing i am not getting clear is that how to pass "Selected item to do these two things" and to check before closing panel that is there any text in textbox fields or not. User View Model Code:
嗨,我正在使用 WPF 和 MVVM,我的应用程序中有“编辑/更新”面板,它更新网格中的选定数据。它工作正常。我想添加一个按钮“关闭按钮”和“一次检查用户是否选择了项目。如果他没有选择任何项目并点击“编辑按钮”它会向用户显示一个消息框来选择一个项目编辑。我不清楚的是如何通过“选定的项目来做这两件事”并在关闭面板之前检查文本框字段中是否有任何文本。用户查看模型代码:
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
}
}
User View Window.Xaml Panel1
用户视图窗口 .Xaml Panel1
<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>
Panel2:
面板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>
(If my question is not clear to you plesae ask me. Thank you)
(如果我的问题不清楚,请问我。谢谢)
回答by doerig
Create a Property in the ViewModel for saving the selected User:
在 ViewModel 中创建一个用于保存所选用户的属性:
public User SelectedUser { get; set; }
Bind SelectedItem of the ListView to this Property:
将 ListView 的 SelectedItem 绑定到此属性:
<ListView Name="UserGrid" ItemsSource="{Binding Users}" SelectedItem="{Binding SelectedUser}">
Now you just have to check if the SelectedUser
property is null.
现在您只需要检查该SelectedUser
属性是否为空。
回答by Dennis
how to pass "Selected item to do these two things"
如何通过“选定的项目来做这两件事”
This usually can be achieved with SelectedSomething
property in your view model. This property should be bound to SelectedItem
of control.
这通常可以通过SelectedSomething
视图模型中的属性来实现。此属性应绑定到SelectedItem
控制。
and to check before closing panel that is there any text in textbox fields or not
并在关闭面板之前检查文本框字段中是否有任何文本
This is called "validation". WPF supports validation in several ways, one of them is implementing IDataErrorInfo
in your view model. I'd recommend this way, because it is a de facto standard for .NET (it is used in WinForms and ASP .NET as well).
这称为“验证”。WPF 以多种方式支持验证,其中之一是IDataErrorInfo
在您的视图模型中实现。我推荐这种方式,因为它是 .NET 的事实上的标准(它也用于 WinForms 和 ASP .NET)。
one check to see whether user has selected item or not. If he doesn't select any item and click on "Edit Button" It will show a MessageBox to user to select an item to edit
一次检查以查看用户是否选择了项目。如果他没有选择任何项目并单击“编辑按钮”,它将向用户显示一个 MessageBox 以选择要编辑的项目
Again, usually, this being solved with ICommand
instance, bound to the button. If ICommand.CanExecute
returns false, bound button becomes disabled.
同样,通常,这是通过ICommand
绑定到按钮的实例解决的。如果ICommand.CanExecute
返回 false,绑定按钮将被禁用。
For example, you should check for validation errors in CanExecute
for command, bound to Close
button, and return false, if there are any errors. Or you should check SelectedSomething
property in CanExecute
for command, bound to Edit
button, and return false
, if SelectedSomething == null
.
例如,您应该检查 forCanExecute
命令中的验证错误,绑定到Close
按钮,如果有任何错误,则返回 false。或者你应该检查命令的SelectedSomething
属性CanExecute
,绑定到Edit
按钮,然后返回false
,如果SelectedSomething == null
。
In MVVM world thing becomes easier, if you use RelayCommand
/DelegateCommand
as the default ICommand
implementation.
在 MVVM 世界中,如果您使用RelayCommand
/DelegateCommand
作为默认ICommand
实现,事情会变得更容易。
Update.
更新。
A code sample for commands. View model:
命令的代码示例。查看型号:
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:
XAML:
<Button Content="Edit" Command="{Binding EditCommand}"/>