2010-07-14 97 views
0

我正在尝试做一些应该脑死的简单的事情,但是,我无法让它工作。我正在显示列表框中的项目列表。我已将复选框添加到列表框,以便用户可以选择多个项目。但是,即使列表中绑定到ListBox的对象具有“IsSelected”属性,它也没有被绑定。我可以使用一些帮助,因为这使我疯狂。在WPF中绑定ListBox的IsSelectedProperty不起作用。需要帮助

<Style x:Key="CheckBoxListStyle" TargetType="{x:Type ListBox}"> 
    <Setter Property="SelectionMode" Value="Multiple"></Setter> 
    <Setter Property="ItemContainerStyle"> 
     <Setter.Value> 
      <Style TargetType="{x:Type ListBoxItem}"> 
       <Setter Property="Margin" Value="2"/> 
       <Setter Property="Template"> 
        <Setter.Value> 
         <ControlTemplate TargetType="{x:Type ListBoxItem}"> 
          <CheckBox Focusable="False" 
             IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"> 
           <ContentPresenter></ContentPresenter> 
          </CheckBox> 
         </ControlTemplate> 
        </Setter.Value> 
       </Setter> 
      </Style> 
     </Setter.Value> 
    </Setter> 

<ListBox 
         Style="{StaticResource CheckBoxListStyle}" 
         IsEnabled="{Binding Path=SpecificClients.Value, Mode=OneWay}" 
         ItemsSource="{Binding Path=SelectedClients}" 
         VirtualizingStackPanel.IsVirtualizing="True" 
         VirtualizingStackPanel.VirtualizationMode="Recycling" 
         ScrollViewer.VerticalScrollBarVisibility="Auto" 
         MaxHeight="95"> 
       </ListBox> 

在视图模型我有以下几点:

public IEnumerable<SelectedClientVM> SelectedClients 
.... 
public class SelectedClientVM 
    { 
     public bool IsSelected { get; set; } 
     public Client Client { get; set; } 
     public override string ToString() 
     { 
      return Client.SearchText; 
     } 
    } 

回答

1

我认为你想要什么可以通过定义一个DataTemplate用于列表框中的每个项目来更好地实现。 A DataTemplate指定如何在列表框中呈现单个数据片段(在您的案例中为Client)。

这是我的一个简单的DataTemplate的XAML。

<DataTemplate x:Key="clientTemplate" DataType="{x:Type local:Client}"> 
     <Grid> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="Auto" /> 
       <ColumnDefinition /> 
      </Grid.ColumnDefinitions> 
      <CheckBox IsChecked="{Binding IsSelected}" /> 
      <TextBlock Grid.Column="1" Text="{Binding Name}" Margin="5,0,0,0" /> 
     </Grid> 
    </DataTemplate> 

以下是我引用它在列表框声明:

<ListBox ItemsSource="{Binding SelectedClients}" 
     VirtualizingStackPanel.IsVirtualizing="True" 
     ItemTemplate="{StaticResource clientTemplate}" /> 

其次,格兰特的回答,你要确保你的Client类实现INotifyPropertyChanged。另外,您需要使用支持更改通知的集合公开您的客户端列表。我通常使用ObservableCollection<T>

+0

thanx兄弟来处理。那钉了它。这让我疯狂。我尝试绑定到数据模板中的ListBoxItem,或者使用RelativeAncestor,但它们都不起作用。我从来没有想过为我使用的虚拟机类型使用数据模板,但现在我明白了......似乎很明显。 – Keith 2010-07-14 19:04:33

+0

好,很高兴为你解决了它。对我而言,一旦我将我的大脑包裹在模型中,这绝对是一个灯泡爆发的时刻。 – 2010-07-14 20:13:30

0

这可能不是唯一的问题,但如果你想在视图更新根据您的视图模型,你必须实现INotifyPropertyChanged (或者做类似工作的东西)在你的IsSelected属性上。

+0

问题是ViewModel没有通过视图中的更改得到更新。 当我想从视图模型更新视图时,它是一次性的事情,并通过手动触发OnPropertychanged(“SelectedClients”) – Keith 2010-07-14 17:03:40