简体   繁体   English

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

[英]How do you bind user control properties to properties of an observable object contained in observable collection

I am using MVVMLight and need to be able to make programmatic edits to the properties about 12 toggle boxes during the initialization of a View.我正在使用 MVVMLight 并且需要能够在视图初始化期间对大约 12 个切换框的属性进行编程编辑。 Since there are so many of them and I would like to iterate through the linked properties I am trying to use an ObservableCollection of an ObservableObject containing the values to be bound to the properties of the toggle buttons.由于它们太多,我想遍历链接的属性,我尝试使用ObservableCollectionObservableObject其中包含要绑定到切换按钮属性的值。 I am unsure if this is a binding issue or incorrect implementation of the INotifyPropertyChanged interface inherited from the ObservableObject .我不确定这是绑定问题还是从ObservableObject继承的INotifyPropertyChanged接口的错误实现。

Here is the class containing the properties I wish to bind to:这是包含我希望绑定到的属性的类:

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

Here is the instantiation of my ObservableCollection :这是我的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;
}

And here is how I am attempting to bind it:这是我尝试绑定它的方式:

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

I have confirmed the binding of the View to the ViewModel class is working properly.我已经确认 View 到 ViewModel 类的绑定工作正常。 I have also tried binding without setting the DataContext of the containing Grid first, like:我也尝试过绑定而不先设置包含网格的DataContext ,例如:

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

For clarification: Each one of CavitySelect items is related to a toggle button in a GridView, and the properties will be initialized based on an input not shown.澄清一下:每个 CavitySelect 项都与 GridView 中的一个切换按钮相关,并且属性将根据未显示的输入进行初始化。

Displaying a collection of items显示项目集合

Your question doesn't make it perfectly clear, but I believe you want to show a list of items in your UI;你的问题并没有说得很清楚,但我相信你想在你的 UI 中显示一个项目列表; however, as currently implemented, your XAML is really structured to show a single item.但是,正如当前实现的那样,您的 XAML 确实结构化为显示单个项目。

To show a list, you'll want to look at any of the variety of collection views (eg ListView , GridView , etc.).要显示列表,您需要查看各种集合视图中的任何一种(例如ListViewGridView等)。

For example:例如:

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

To only show specific items, you should filter the list in the ViewModel, rather than binding the visibility.要仅显示特定项目,您应该在 ViewModel 中过滤列表,而不是绑定可见性。 If the items visible doesn't change while being displayed, simply filter the list when you're populating it.如果可见的项目在显示时没有改变,只需在填充列表时过滤列表。

If, however, the visibilities will change and you want the view to reflect those changes, look at implementing a filter for your items source as explained in this question: How do I Filter ListView in WPF?但是,如果可见性会发生变化并且您希望视图反映这些变化,请查看为您的项目源实现过滤器,如以下问题中所述: 如何在 WPF 中过滤 ListView? . .

As you're already using an ObservableCollection and ObservableObject, everything should automatically update.由于您已经在使用 ObservableCollection 和 ObservableObject,所以一切都应该自动更新。

Showing a single item from a collection显示集合中的单个项目

If I read your question wrong and you want to know how to show a single item from a collection, there's a couple of different ways of approaching this:如果我读错了您的问题并且您想知道如何显示集合中的单个项目,则有几种不同的方法可以解决这个问题:

  1. Expose the individual item as a property on the ViewModel so the View doesn't have to dig into the list.将单个项目作为 ViewModel 上的一个属性公开,这样 View 就不必深入到列表中。
  2. Create a converter that takes in the collection and index, then pulls out the correct item.创建一个接收集合和索引的转换器,然后提取正确的项目。

I would highly recommend going with option 1, though, as it most conforms with MVVM, producing the cleanest and most testable code.不过,我强烈建议使用选项 1,因为它最符合 MVVM,生成最干净和最可测试的代码。

For example:例如:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM