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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 12:16:03  来源:igfitidea点击:

How to get selected item in MVVM-WPF

c#.netwpfmvvm

提问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 SelectedUserproperty is null.

现在您只需要检查该SelectedUser属性是否为空。

回答by Dennis

how to pass "Selected item to do these two things"

如何通过“选定的项目来做这两件事”

This usually can be achieved with SelectedSomethingproperty in your view model. This property should be bound to SelectedItemof 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 IDataErrorInfoin 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 ICommandinstance, bound to the button. If ICommand.CanExecutereturns false, bound button becomes disabled.

同样,通常,这是通过ICommand绑定到按钮的实例解决的。如果ICommand.CanExecute返回 false,绑定按钮将被禁用。

For example, you should check for validation errors in CanExecutefor command, bound to Closebutton, and return false, if there are any errors. Or you should check SelectedSomethingproperty in CanExecutefor command, bound to Editbutton, 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/DelegateCommandas the default ICommandimplementation.

在 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}"/>