将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>
答案 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。