Как связать коллекцию элементов со списком флажков? - PullRequest
2 голосов
/ 30 июля 2010

Извините за смутное описание, я не могу придумать лучшего способа его выразить.

Допустим, у моего ViewModel есть свойство:

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

иКласс подсистем:

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

    public bool IsSelected { get; set; }
}

В представлении я хотел бы связать свойство SubSystems с, как мне кажется, списком флажков, к которым привязаны свойства IsChecked и Name элемента CheckBox.для их соответствующих свойств, IsChecked для IsSelected и Content for Name.

Я знаю, что могу создать ListBox в 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 -

Просто чтобы прояснить, все примеры заполняют поле, но ни один из примеров не ломается в точках останова в установщиках.

Ответы [ 4 ]

2 голосов
/ 30 июля 2010

Как насчет этого:

<DataTemplate>
    <StackPanel Orientation="Horizontal">
        <CheckBox IsChecked={Binding IsSelected, Mode=TwoWay} /><TextBlock Text={Binding Name} />
    </StackPanel>
</DataTemplate>
1 голос
/ 30 июля 2010

Вы имеете в виду что-то подобное?

Класс подсистемы

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
}

ViewModel

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

1 голос
/ 30 июля 2010

Я думаю, что вместо ListBox вы, вероятно, захотите ItemsControl. ListBoxes предполагают, что вы хотите выбрать один из SubSystem, но на самом деле вы просто хотите упорядочить элементы с помощью шаблонов данных:

<ItemsControl ItemsSource="{Binding SubSystems}">
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <Checkbox IsChecked="{Binding IsSelected, Mode=TwoWay}" Content="{Binding Name}" />
    </DataTemplate>
  <ItemsControl.ItemTemplate>
</ItemsControl>
1 голос
/ 30 июля 2010

Измените шаблон 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" для CheckBoxes, иначе ваши пользователи смогут вкладываться в них.

EDIT:

Кроме того, из того, что вы добавили, может отсутствовать свойство ElementName (если SubSystems НЕ является DataContext вашего окна, вам необходимо указать, откуда исходит свойство SubSystems со свойством привязки ElementName):

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