绑定所选项目以查看模型

时间:2016-06-30 09:04:06

标签: c# .net wpf xaml

将ListBox selectedItem绑定到我的ViewModel需要什么? 视图模型SelectedClient始终为null。

通过名为ClientClickedCommand的命令成功调用ClientSelected。但是当我尝试在ClientSelected方法中访问视图模型SelectedClient时,它为null并抛出异常。

XAML

<ListBox x:Name="lbSlaves" Width="300" Grid.Row="1"  ItemsSource="{Binding Slaves}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
             SelectedItem="{Binding SelectedClient, Mode=TwoWay}"
             >
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel  />
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <CheckBox  IsChecked="{Binding Checked ,Mode=TwoWay}"/>
                    <Button 
                        Command="{Binding  ElementName=MainGrid, Path=DataContext.ClientClickedCommand}"                    
                        >
                        <TextBlock Text="{Binding MachineName, Mode=OneWay}" />
                    </Button>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

VIEVMODEL(绑定到DataContext)

        private MyClient _selectedClient;
    public MyClient SelectedClient
    {
        get {
            return _selectedClient;
        }
        set
        {
            if (value != _selectedClient)
            {
                _selectedClient = value;
                NotifyPropertyChanged("SelectedClient");
            }
        }
    }

    public string _infoText;
    public string InfoText { 
        get {
        return _infoText;
    }
        set {
            if (value != _infoText)
            {
                _infoText = value;
                NotifyPropertyChanged("InfoText");
            }
        }
    }

    private void ClientSelected()
    {
        var message = " - " + SelectedClient.MachineName + " was clicked";
        InfoText += message;

    }

ClientClickedCommand = new Command(ClientSelected,  ()=>  true); 



  public ICommand ClientClickedCommand
        {
            get;
            set;
        }

更新:我现在尝试通过CommandParameter绑定SelectedClient,就像这样

  <ListBox x:Name="lbSlaves" Width="600" Grid.Row="1" 
             ItemsSource="{Binding Slaves}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" >
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel  />
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <WrapPanel Orientation="Horizontal" Width="150" Height="60">
                    <CheckBox  IsChecked="{Binding Checked ,Mode=TwoWay}"/>
                    <TextBlock Text="{Binding MachineName, Mode=OneWay}" />
                    <Button 
                        Content="Do something"  
                        Command="{Binding  ElementName=MainGrid, Path=DataContext.ClientClickedCommand}" 
                        CommandParameter="{Binding ElementName=MainGrid, Path=DataContext.SelectedClient, Mode=TwoWay}" />

                    <Button Content="Do another thing>" />

                </WrapPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

2 个答案:

答案 0 :(得分:2)

按钮可能会吞下鼠标,但除此之外,您的SelectedClient属性所在的位置并不清楚。它似乎在MyClient类中,而它应该在Slaves的同一级别。

编辑: 如果你想保留自己的按钮,请使用CommandParameter,如下所示:

Command="{Binding  ElementName=MainGrid, Path=DataContext.ClientClickedCommand}" CommandParameter="{Binding}"

我不确定new Command (...)的作品,但是有些命令会带参数,所以下一部分应如下所示:

private void ClientSelected(MyClient client)
{
    SelectedClient = client;
    var message = " - " + SelectedClient.MachineName + " was clicked";
    InfoText += message;

}

答案 1 :(得分:2)

大多数人已经告诉过您这个问题 - ListViewItem中的按钮正在消耗您的点击事件。将命令分配给按钮时,WPF将在后台订阅按钮的单击事件。处理点击事件的默认行为是设置e.Handled = true;,这会导致单击鼠标时出现的其他事件停止工作。

您是否单独使用SelectedClient和命令并不太清楚。如果你想知道的是用户点击了ListViewItem,你就不能使用命令。

public MyClient SelectedClient
{
    get
    {
        return _selectedClient;
    }
    set
    {
        if (value != _selectedClient)
        {
            _selectedClient = value;
            ClientSelected();
            NotifyPropertyChanged("SelectedClient");
        }
    }
}

如果选择ListViewItem与按钮的目标不同,那么您需要考虑为每个ListViewItem需要一个按钮的原因。从逻辑上讲,如果所有项目都需要做类似性质的事情,您可以将按钮放在ListView之外。这样,按钮不会搞乱你的ListView。