c# - 如何将用户控件属性绑定(bind)到可观察集合中包含的可观察对象的属性

标签 c# wpf mvvm mvvm-light observablecollection

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

这是包含我希望绑定(bind)到的属性的类:

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;
}

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

<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 类的绑定(bind)工作正常。我也试过绑定(bind)而不设置 DataContext首先是包含网格的,例如:

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

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

最佳答案

显示项目集合

您的问题并没有说得很清楚,但我相信您想在 UI 中显示项目列表;但是,正如当前实现的那样,您的 XAML 实际上是结构化的以显示单个项目。

要显示列表,您需要查看各种 Collection View 中的任何一种(例如 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 中过滤列表,而不是绑定(bind)可见性。如果可见的项目在显示时没有改变,只需在填充列表时过滤列表。

但是,如果可见性将发生变化,并且您希望 View 反射(reflect)这些变化,请查看为您的项目源实现过滤器,如以下问题所述:How do I Filter ListView in WPF? .

由于您已经在使用 ObservableCollection 和 ObservableObject,所以一切都应该自动更新。

显示集合中的单个项目

如果我读错了您的问题,并且您想知道如何显示集合中的单个项目,则有几种不同的方法可以解决此问题:
  • 将单个项目公开为 ViewModel 上的属性,这样 View 就不必深入列表。
  • 创建 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;
    }
    

    关于c# - 如何将用户控件属性绑定(bind)到可观察集合中包含的可观察对象的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60330172/

    相关文章:

    C# 通过两个日期将时间写为字符串

    ASP.Net 还是 WPF (C#)?

    javascript - 使用标签名称插入的组件不起作用

    c# - 如何在添加文件后但发送前获取 RestRequest 正文内容

    c# - CaSTLe Log4Net 设施不记录

    c# - Asp.Net Core 2.0 中 Httpcontext.Current.Request.Files 的替代方案是什么?

    wpf - 调用线程无法访问该对象,因为另一个线程拥有它

    .net - 将 System.Drawing.Font.Size 转换为 WPF FontSize

    wpf - ContextMenu 绑定(bind)到 ObservableCollection<MenuItem> 不刷新数据

    WPF OnPropertyChanged 重复代码