【问题标题】:How to show data from selected item in listbox wpf using mvvm?如何使用 mvvm 在列表框 wpf 中显示所选项目的数据?
【发布时间】:2014-02-10 09:27:54
【问题描述】:

我只是在 WPF 和 MVVM 表单上做一些练习 到目前为止,我刚刚完成了从数组加载数据的普通列表框,当索引更改时,它将其他数据加载到表单上的文本块中

不过,我想更改此示例。我希望用户在列表框中选择一个字段,然后单击一个按钮以显示所有其他数据

所以,表单是(用户控件): 当有人选择时,比如 Cena,他们会看到右侧的数据已填写。

我的 .xaml 代码是:

<UserControl x:Class="SuperstarsRoster.RosterView"
         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:SuperstarsRoster"
         xmlns:WpfToolkit="http://schemas.microsoft.com/wpf/2008/toolkit"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="600">

<UserControl.DataContext>
    <local:RosterViewModel/>
</UserControl.DataContext>
<Grid x:Name="LayoutRoot" Background="White" >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="250"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <!--SelectedItem="{Binding SelectedPerson}"-->
    <ListBox Grid.Column="0" Margin="0"
              ItemsSource="{Binding RosterList}"
              DisplayMemberPath="Name"
              Name="lstRoster"
              Height="250"
              VerticalAlignment="Top"/>
    <Button Content="Exit" Height="23" HorizontalAlignment="Left" VerticalAlignment="Bottom" Name="btnExit" Width="150" Command="{Binding ButtonCommand}" CommandParameter="Hai" />
    <Grid x:Name="PersonDetails" Grid.Column="1" DataContext="{Binding SelectedPerson}" Margin="5">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition Width="150"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition Height="20"/>
            <RowDefinition Height="20"/>
            <RowDefinition Height="20"/>
            <RowDefinition Height="20"/>
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Grid.ColumnSpan="2" Text="Person Details" FontSize="15"/>

        <TextBlock Grid.Row="1" Grid.Column="0" Text="Name"/>
        <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Name,Mode=TwoWay}"/>

        <TextBlock Grid.Row="2" Grid.Column="0" Text="Brand"/>
        <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Brand,Mode=TwoWay}"/>

        <TextBlock Grid.Row="3" Grid.Column="0" Text="Type"/>
        <TextBlock Grid.Row="3" Grid.Column="1" Text="{Binding Type,Mode=TwoWay}"/>

        <Button Grid.Row="4" Content="Choose" Height="23" HorizontalAlignment="Left" VerticalAlignment="Bottom" Name="btnChoose" Width="90" Command="{Binding ChooseCommand}" CommandParameter="{Binding ElementName=lstRoster,Path=SelectedPerson}" />
    </Grid>
</Grid>

我的问题是显示按钮:

<Button Grid.Row="4" Content="Choose" Height="23" HorizontalAlignment="Left" VerticalAlignment="Bottom" Name="btnChoose" Width="90" Command="{Binding ChooseCommand}" CommandParameter="{Binding ElementName=lstRoster,Path=SelectedPerson}" />

我不知道在这里做什么。我不知道CommandParameters应该是空的,还是里面有东西。

我的 ViewModel 代码是:

#region Show Button

    private ICommand m_ShowCommand;
    public ICommand ShowCommand
    {
        get
        {
            return m_ShowCommand;
        }
        set
        {
            m_ShowCommand = value;
        }
    }

    public void Selected(object obj)
    {
        RaisePropertyChanged("SelectedPerson");
    }

    #endregion

我感觉我的 Selected 代码不正确。在 ViewModel 代码上还有:

 #region Roster Details

    public ObservableCollection<Roster> rosterList;
    public Roster selectedPerson;


    public RosterViewModel()
    {

        ButtonCommand = new RelayCommand(new Action<object>(ShowMessage));
        ShowCommand = new RelayCommand(new Action<object>(Selected));
        rosterList = new ObservableCollection<Roster>()
        {
            new Roster(){Name="Batista", Brand="Smackdown!", Type="Heel"},
            new Roster(){Name="The Rock", Brand="RAW", Type="Face"},
            new Roster(){Name="John Cena", Brand="RAW", Type="Face"},
            new Roster(){Name="Randy Orton", Brand="Smackdown!", Type="Heel"}
        };

        RaisePropertyChanged("SelectedPerson");
    }

    #endregion

ShowCommand 是按钮事件,但我不知道该放什么。

理想情况下,用户选择 Cena,点击显示,文本块将填充数组中的数据。

我的 RelayCommand 类(所有按钮点击的默认值)如下所示:

class RelayCommand : ICommand
{
    private Action<object> _action;

    public RelayCommand(Action<object> action)
    {
        _action = action;
    }

    #region ICommand Members

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        _action(parameter);
    }

    #endregion

这里应该有更多的东西吗?还是在 ViewModel 中?

我使用的是 MVVM,所以我的代码中没有代码在类后面。

退出按钮有效,这就是我知道命令有效的原因。

编辑

我现在更改了一些代码。首先,显示按钮位于具有数据上下文设置的网格中。那是拿出来的。接下来,两个按钮共享相同的命令(ButtonCommand),但都有不同的参数。 Exit是“Exit”,选择是“Hai”

在 ViewModel 代码中,添加和更改了以下内容

 public string Name { get; set; }
    public string Brand { get; set; }
    public string Type { get; set; }

    #region Button Work
    private ICommand m_ButtonCommand;
    public ICommand ButtonCommand
    {
        get
        {
            return m_ButtonCommand;
        }
        set
        {
            m_ButtonCommand = value;
        }
    }

    public void DoAction(object obj)
    {
        if (obj.ToString() == "Hai")
        {
            if (selectedPerson != null)
            {
                this.Name = selectedPerson.Name;
                this.Brand = selectedPerson.Brand;
                this.Type = selectedPerson.Type;
                RaisePropertyChanged(null);
            }                
        }
        if (obj.ToString() == "Exit")
        {
            MessageBox.Show("This program will now close");
            Environment.Exit(0);
        }
    }
    #endregion

这样,数据就设置好了,我可以在需要时填充字段。

先初始化一下

 public RosterViewModel()
    {
        ButtonCommand = new RelayCommand(new Action<object>(DoAction));

所以,它现在可以工作了。

【问题讨论】:

    标签: c# wpf xaml mvvm listbox


    【解决方案1】:

    你真的有几个选择:

    (1) 拥有绑定到SelectedItemListBox 的VM 属性,然后您不需要使用按钮命令发送任何参数...您只需执行ChooseCommand在当前的SelectedItem(你的虚拟机知道)上。

    (2) 将SelectedItem 作为命令的参数传入,如下所示...

    <Button Grid.Row="4" Content="Choose" Height="23" HorizontalAlignment="Left"
        VerticalAlignment="Bottom" Name="btnChoose" Width="90"
        Command="{Binding ChooseCommand}" 
        CommandParameter="{Binding ElementName=MyListBox,Path=SelectedItem}" />
    

    请注意,您需要为 ListBox 命名 (x:Name="MyListBox"),并且您的 CommandParameter 指的是该 ListBox 及其 SelectedItem 属性。

    【讨论】:

    • 我总是推荐第一个选项,因为它允许您对行为进行单元测试。
    • 谢谢大家。我选择了第一个,并改变了我的编码。我在 DataContext 中有按钮,所以我把它拿出来了。我会和编辑显示固定的例子
    猜你喜欢
    • 2016-03-22
    • 2017-03-29
    • 1970-01-01
    • 2012-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    相关资源
    最近更新 更多