2010-07-30 65 views
2

對於模糊的描述,我想不出一個更好的方式來表達它。如何將一組項目綁定到複選框的列表框?

比方說,我的ViewModel有一個屬性如下:

public List<MyClass> SubSystems { get; set; } 

和子系統類:

public class SubSystem 
{ 
    public string Name { get; set; } 

    public bool IsSelected { get; set; } 
} 

在視圖中,我想給SubSystems屬性綁定,什麼我認爲會是一個複選框列表,CheckBox的IsChecked和Name屬性綁定到它們各自的屬性,IsSelected for IsSelected和Content for Name。

我知道我可以做一個列表框在XAML,但我不知道我怎麼會去這樣做使用綁定和集合..

感謝您的幫助!

編輯 -

這裏的XAML:

<GroupBox Header="Sub-Systems" Grid.Column="0" Grid.Row="0" Margin="5"> 
    <Grid> 
     <Grid.Resources> 
      <DataTemplate x:Key="checkBox"> 
       <StackPanel Orientation="Horizontal"> 
        <CheckBox IsChecked="{Binding IsSelected}" /> 
        <TextBlock Text="{Binding Name}" /> 
       </StackPanel> 
      </DataTemplate> 
     </Grid.Resources> 
     <ListBox ItemTemplate="{StaticResource checkBox}" ItemsSource="{Binding SubSystems}" /> 
    </Grid> 
</GroupBox> 

編輯#2 -

只是爲了澄清,所有的例子填充盒,但沒有一個例子是上破制定者的斷點。

+0

如果您的SubSystem對象在其他地方更改,您還需要NotifyPropertyChanged,它應該通知CheckBox它已更改,因此CheckBox可以自行更新。 – Carlo 2010-07-30 19:31:31

回答

1

你的意思是這樣的?

子系統類

public class SubSystem : INotifyPropertyChanged 
{ 
    private string mName; 
    private Boolean mIsSelected = false; 

    public SubSystem() 
    { 
    } 

    public SubSystem(string name, Boolean isSelected) 
    { 
     this.Name = name; 
     this.IsSelected = isSelected; 
    } 

    public string Name 
    { 
     get { return mName; } 
     set 
     { 
      if (mName != value) 
      { 
       mName = value; 
       if (PropertyChanged != null) 
        PropertyChanged(this, new PropertyChangedEventArgs("Name")); 
      } 
     } 
    } 

    public Boolean IsSelected 
    { 
     get { return mIsSelected; } 
     set 
     { 
      if (mIsSelected != value) 
      { 
       mIsSelected = value; 
       if (PropertyChanged != null) 
        PropertyChanged(this, new PropertyChangedEventArgs("IsSelected")); 
      } 
     } 
    } 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    #endregion 
} 

視圖模型

ObservableCollection<SubSystem> mSubSystems = new ObservableCollection<SubSystem>(); 
public ObservableCollection<SubSystem> SubSystems 
{ 
    get { return mSubSystems; } 
    set { mSubSystems = value; } 
} 

查看

<ListBox x:Name="lstSubsystems" ItemsSource="{Binding SubSystems}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <CheckBox IsChecked="{Binding IsSelected}"> 
       <ContentPresenter Content="{Binding Name}" /> 
      </CheckBox> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

希望幫助, Wts

+0

這正是我正在尋找的 - 謝謝! – 2010-07-30 20:38:19

+0

@Ian P:記住在CheckBox上選擇Focusable =「False」,這樣你的用戶就不能進入它,否則它的外觀和感覺真的很奇怪。 – Carlo 2010-07-30 21:16:33

2

如何:

<DataTemplate> 
    <StackPanel Orientation="Horizontal"> 
     <CheckBox IsChecked={Binding IsSelected, Mode=TwoWay} /><TextBlock Text={Binding Name} /> 
    </StackPanel> 
</DataTemplate> 
+0

由於某些未知的原因,在我的ViewModel中,當我使用它時,setter永遠不會被調用。我在ListBox中添加了x:Key =「checkBox」到和ItemTemplate =「{StaticResource checkBox}」。它似乎是正確渲染,只是沒有約束力。 – 2010-07-30 19:20:19

+0

查看我編輯的XAML原始文章。 – 2010-07-30 19:22:27

+0

啊,是的,修好了。 Mode = TwoWay就是你缺少的東西 – 2010-07-30 19:30:19

1

修改ListBox.ItemTemplate使用複選框,並綁定到CheckBox.IsChecked和SubSystem.IsSelected到CheckBox.Content SubSystem.Name:

XAML:

<ListBox ItemsSource="{Binding}"> 
    <ListBox.ItemTemplate> 
    <DataTemplate> 
    <CheckBox IsChecked="{Binding IsSelected}" Content="{Binding Name}" Margin="5" Focusable="False" /> 
    </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

C#:

private void window1_Loaded(object sender, RoutedEventArgs e) 
{ 
this.SubSystems = new List<SubSystem>(); 

this.SubSystems.Add(new SubSystem() { Name = "SubSystem 1", IsSelected = false }); 
this.SubSystems.Add(new SubSystem() { Name = "SubSystem 2", IsSelected = false }); 
this.SubSystems.Add(new SubSystem() { Name = "SubSystem 3", IsSelected = true }); 
this.SubSystems.Add(new SubSystem() { Name = "SubSystem 4", IsSelected = false }); 
this.SubSystems.Add(new SubSystem() { Name = "SubSystem 5", IsSelected = true }); 

this.DataContext = this.SubSystems; 
} 

並確保您將Focusable =「False」設置爲複選框,否則您的用戶將能夠選中它們。

編輯:

從你加入你可能會丟失的ElementName屬性(如果子系統是不是你的窗口的DataContext的,你需要指定子系統屬性是從與的ElementName綁定來

而且屬性):

<ListBox ItemTemplate="{StaticResource checkBox}" ItemsSource="{Binding ElementName=window1, Path=SubSystems}" /> 
1

我認爲這不是一個ListBox,你可能想要一個ItemsControl。列表框假設你要選擇的SubSystem之一,但說真的,你只是想用數據模板,安排的項目:

<ItemsControl ItemsSource="{Binding SubSystems}"> 
    <ItemsControl.ItemTemplate> 
    <DataTemplate> 
     <Checkbox IsChecked="{Binding IsSelected, Mode=TwoWay}" Content="{Binding Name}" /> 
    </DataTemplate> 
    <ItemsControl.ItemTemplate> 
</ItemsControl> 
相關問題