将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>

最佳答案

该按钮可能会吞下鼠标单击,但是除此之外,还不清楚您的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;

}

10-04 11:48