如何将用户控件属性绑定到可观察集合中包含的可观察对象的属性
How do you bind user control properties to properties of an observable object contained in observable collection
我正在使用 MVVMLight,并且需要能够在视图初始化期间对大约 12 个切换框的属性进行编程编辑。由于它们太多了,我想遍历链接的属性,我尝试使用 ObservableCollection
的 ObservableObject
包含要绑定到切换按钮属性的值。我不确定这是从 ObservableObject
.
继承的 INotifyPropertyChanged
接口的绑定问题还是不正确的实现
这是包含我希望绑定到的属性的 class:
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 class 的绑定工作正常。我也试过绑定而不先设置包含网格的 DataContext
,比如:
<ToggleButton DataContext="{Binding CavTogglesProperties[t11]}" ... />
澄清一下:
CavitySelect 中的每一项都与 GridView 中的切换按钮相关,属性将根据未显示的输入进行初始化。
显示项目集合
您的问题没有说得很清楚,但我相信您想在 UI 中显示项目列表;但是,按照目前的实施方式,您的 XAML 的结构实际上是为了显示单个项目。
要显示列表,您需要查看各种集合视图(例如 ListView, GridView 等)。
例如:
<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,所以一切都应该自动更新。
显示集合中的单个项目
如果我读错了你的问题,而你想知道如何显示集合中的单个项目,有几种不同的方法可以解决这个问题:
- 在 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;
}
我正在使用 MVVMLight,并且需要能够在视图初始化期间对大约 12 个切换框的属性进行编程编辑。由于它们太多了,我想遍历链接的属性,我尝试使用 ObservableCollection
的 ObservableObject
包含要绑定到切换按钮属性的值。我不确定这是从 ObservableObject
.
INotifyPropertyChanged
接口的绑定问题还是不正确的实现
这是包含我希望绑定到的属性的 class:
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 class 的绑定工作正常。我也试过绑定而不先设置包含网格的 DataContext
,比如:
<ToggleButton DataContext="{Binding CavTogglesProperties[t11]}" ... />
澄清一下: CavitySelect 中的每一项都与 GridView 中的切换按钮相关,属性将根据未显示的输入进行初始化。
显示项目集合
您的问题没有说得很清楚,但我相信您想在 UI 中显示项目列表;但是,按照目前的实施方式,您的 XAML 的结构实际上是为了显示单个项目。
要显示列表,您需要查看各种集合视图(例如 ListView, GridView 等)。
例如:
<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,所以一切都应该自动更新。
显示集合中的单个项目
如果我读错了你的问题,而你想知道如何显示集合中的单个项目,有几种不同的方法可以解决这个问题:
- 在 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;
}