简体   繁体   English

如何在MVVM-WPF中获取所选项目

[英]How to get selected item in MVVM-WPF

Hi I am using WPF and MVVM, There is "Edit/Update" Panel in my application it updates selected data in Grid. 嗨我正在使用WPF和MVVM,我的应用程序中有“编辑/更新”面板,它更新了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: 我想添加一个按钮“关闭按钮”和“一个检查用户是否选择了项目。如果他没有选择任何项目并点击”编辑按钮“它将显示一个MessageBox给用户选择一个项目要编辑。我不清楚的是如何通过“选择项目来做这两件事”并在关闭面板之前检查是否有文本框字段中的文本。用户视图模型代码:

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 用户视图Window.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: 是Panel2:

<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) (如果我的问题不清楚你请问我。谢谢你)

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属性是否为null。

how to pass "Selected item to do these two things" 如何通过“选择项目做这两件事”

This usually can be achieved with SelectedSomething property in your view model. 这通常可以使用视图模型中的SelectedSomething属性来实现。 This property should be bound to SelectedItem of control. 此属性应绑定到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. WPF以多种方式支持验证,其中一种方法是在视图模型中实现IDataErrorInfo I'd recommend this way, because it is a de facto standard for .NET (it is used in WinForms and ASP .NET as well). 我推荐这种方式,因为它是.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. 通常,这通过ICommand实例解决,绑定到按钮。 If ICommand.CanExecute returns false, bound button becomes disabled. 如果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. 例如,您应检查CanExecute for command中的验证错误,绑定到Close按钮,如果有任何错误,则返回false。 Or you should check SelectedSomething property in CanExecute for command, bound to Edit button, and return false , if SelectedSomething == null . 或者,如果SelectedSomething == null ,则应检查CanExecute SelectedSomething属性以获取命令,绑定到“ Edit按钮,并返回false

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM