如何将用户控件属性绑定到可观察集合中包含的可观察对象的属性

问题描述 投票:0回答:1

我正在使用MVVMLight,并且需要能够在View的初始化期间对约12个切换框的属性进行编程编辑。由于它们太多,因此我想遍历链接的属性,因此我尝试使用ObservableCollection中的ObservableObject,其中包含要绑定到切换按钮属性的值。我不确定这是绑定问题还是从INotifyPropertyChanged继承的ObservableObject接口的错误实现。

这里是包含我想绑定到的属性的类:

public class CavitySelect : ObservableObject
{
    private string _Text;
    public string Text
    {
        get { return _Text; }
        set
        {
            _Text = value;
            RaisePropertyChanged("Text");
        }
    }
    private bool _Visible;
    public bool Visible
    {
        get { return _Visible; }
        set
        {
            _Visible = value;
            RaisePropertyChanged("Visible");
        }
    }
    private bool _Toggle;

    public bool Toggle
    {
        get { return _Toggle; }
        set
        {
            _Toggle = value;
            RaisePropertyChanged("Toggle");
        }
    }

    public CavitySelect()
    {
        Text = "";
        Visible = false;
        Toggle = false;
    }
}

这是我的ObservableCollection的实例:

private ObservableCollection<CavitySelect> _CavTogglesProperties;
public ObservableCollection<CavitySelect> CavTogglesProperties
{
    get { return _CavTogglesProperties; }
    set
    {
        _CavTogglesProperties = value;
        RaisePropertyChanged("CavTogglesProperties");
    }
}

public MyViewModel()
{
    this.CavTogglesProperties = GetCavities();
}    

public ObservableCollection<CavitySelect> GetCavities()
{
    CavitySelect t11 = new CavitySelect();
    CavitySelect t12 = new CavitySelect();
    CavitySelect t13 = new CavitySelect();
    CavitySelect t14 = new CavitySelect();
    CavitySelect t15 = new CavitySelect();
    CavitySelect t16 = new CavitySelect();
    CavitySelect t26 = new CavitySelect();
    CavitySelect t21 = new CavitySelect();
    CavitySelect t22 = new CavitySelect();
    CavitySelect t23 = new CavitySelect();
    CavitySelect t24 = new CavitySelect();
    CavitySelect t25 = new CavitySelect();
    ObservableCollection<CavitySelect> temp = new ObservableCollection<CavitySelect>() {t11,t12,t13,t14,t15,t16,t21,t22,t23,t24,t25,t26};
    return temp;
}

这是我尝试绑定它的方式:

<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BoolToVisibilty"/>
</Window.Resources>
<Grid Background="#FFF4F4F5" Margin="8,165,8,8"  DataContext="{Binding CavTogglesProperties}">
    <ToggleButton DataContext="{Binding t11}" Content="{Binding Text}" IsChecked="{Binding Toggle}" Visibility="{Binding Visible,Converter={StaticResource BoolToVisibilty}}"/> 
</Grid>

我已经确认View与ViewModel类的绑定工作正常。我还尝试了绑定,但没有先设置包含的Grid的DataContext,例如:

<ToggleButton DataContext="{Binding CavTogglesProperties[t11]}" ... />

为了澄清:CavitySelect项中的每个项都与GridView中的切换按钮相关,并且将基于未显示的输入来初始化属性。

c# wpf mvvm mvvm-light observablecollection
1个回答
0
投票

显示项目集合

您的问题并不能很清楚,但是我相信您想在用户界面中显示项目列表;但是,按照目前的实现,您的XAML实际上是显示单个项目的结构。

要显示列表,您需要查看各种集合视图(例如ListViewGridView等)。

例如:

<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BoolToVisibilty"/>
</Window.Resources>
<Grid Background="#FFF4F4F5" Margin="8,165,8,8">
  <ListView ItemsSource="{Binding CavTogglesProperties}">
    <ListView.ItemTemplate>
      <DataTemplate>
        <ToggleButton Content="{Binding Text}" IsChecked="{Binding Toggle}" />
      </DataTemplate>
    </ListView.ItemTemplate>
  </ListView>
</Grid>

仅显示特定项目,应在ViewModel中过滤列表,而不是绑定可见性。如果显示时可见项没有变化,则只需在填充列表时对其进行过滤。

但是,如果可见性会发生变化,并且您希望视图反映这些变化,请按照此问题的说明,为项目源实现过滤器:How do I Filter ListView in WPF?

由于您已经在使用ObservableCollection和ObservableObject,因此所有内容都会自动更新。

显示集合中的单个项目

如果我读错了您的问题,并且您想知道如何显示集合中的单个项目,则有两种不同的处理方式:

  1. 将单个项目公开为ViewModel的属性,因此View不必深入列表。
  2. 创建一个包含集合和索引的converter,然后取出正​​确的项目。

但是,我强烈建议选择选项1,因为它最符合MVVM,可产生最干净,最可测试的代码。

例如:

private ObservableCollection<CavitySelect> _CavTogglesProperties;
public ObservableCollection<CavitySelect> CavTogglesProperties
{
    get { return _CavTogglesProperties; }
    set
    {
        _CavTogglesProperties = value;
        RaisePropertyChanged("CavTogglesProperties");
    }
}

private CavitySelect _SpecificCavToggle;
public CavitySelect SpecificCavToggle
{
    get { return _SpecificCavToggle; }
    set
    {
        _SpecificCavToggle= value;
        RaisePropertyChanged("SpecificCavToggle");
    }
}

public MyViewModel()
{
    this.CavTogglesProperties = GetCavities();
    this.SpecificCavToggle = this.CavTogglesProperties[0];
}    

public ObservableCollection<CavitySelect> GetCavities()
{
    CavitySelect t11 = new CavitySelect();
    CavitySelect t12 = new CavitySelect();
    CavitySelect t13 = new CavitySelect();
    CavitySelect t14 = new CavitySelect();
    CavitySelect t15 = new CavitySelect();
    CavitySelect t16 = new CavitySelect();
    CavitySelect t26 = new CavitySelect();
    CavitySelect t21 = new CavitySelect();
    CavitySelect t22 = new CavitySelect();
    CavitySelect t23 = new CavitySelect();
    CavitySelect t24 = new CavitySelect();
    CavitySelect t25 = new CavitySelect();
    ObservableCollection<CavitySelect> temp = new ObservableCollection<CavitySelect>() {t11,t12,t13,t14,t15,t16,t21,t22,t23,t24,t25,t26};
    return temp;
}
© www.soinside.com 2019 - 2024. All rights reserved.