【发布时间】:2019-06-13 13:33:52
【问题描述】:
我想要实现的是将 ViewModel (mvvm light) 对象的属性以分组方式绑定到一些自制的自定义控件。
所以我创建了一个 CustomControl1,它有一个 Title 属性和一个我自己的自定义类型 SomeDataControl 的 ItemsCollection。
public class CustomControl1 : Control
{
static CustomControl1()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1)));
}
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text", typeof(string), typeof(CustomControl1), new PropertyMetadata(default(string)));
public string Text
{
get { return (string) GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public ObservableCollection<SomeDataControl> _ItemsCollection;
public ObservableCollection<SomeDataControl> ItemsCollection {
get
{
if(_ItemsCollection == null) _ItemsCollection = new ObservableCollection<SomeDataControl>();
return _ItemsCollection;
}
}
}
public class SomeDataControl : DependencyObject
{
public static readonly DependencyProperty LAbelProperty = DependencyProperty.Register(
"LAbel", typeof(string), typeof(SomeDataControl), new PropertyMetadata(default(string)));
public string LAbel
{
get { return (string) GetValue(LAbelProperty); }
set { SetValue(LAbelProperty, value); }
}
public static readonly DependencyProperty DValueProperty = DependencyProperty.Register(
"DValue", typeof(double), typeof(SomeDataControl), new PropertyMetadata(default(double)));
public double DValue
{
get { return (double) GetValue(DValueProperty); }
set { SetValue(DValueProperty, value); }
}
}
我还添加了一个样式来将控件的内容呈现到 ItemsControl 中,并将值绑定到适当的字段,如下所示:
<Style x:Key="ControlStyle" TargetType="local:CustomControl1">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<StackPanel>
<Label Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Text}"></Label>
<ItemsControl ItemsSource="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ItemsCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Content="{Binding Path=LAbel}" />
<Label Content="{Binding Path=DValue}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我将所有这些都放在我的视图中,并将视图模型作为 DataContext,这样我就可以达到这些值。
<Window x:Class="BindingTest.MainWindow" x:Name="thisControl" DataContext="{Binding Source={StaticResource Locator}, Path=VM}">
...
<local:CustomControl1 Text="{Binding Path=DataContext.Text, ElementName=thisControl}" Style="{StaticResource ControlStyle}" >
<local:CustomControl1.ItemsCollection>
<local:SomeDataControl LAbel="Apple" DValue="{Binding Path=DataContext.DVal1, Mode=TwoWay, ElementName=thisControl}">
<local:SomeDataControl LAbel="Peach" DValue="{Binding Path=DataContext.DVal2, Mode=TwoWay, ElementName=thisControl}">
<local:SomeDataControl LAbel="Pear" DValue="{Binding Path=DataContext.DVal3, Mode=TwoWay, ElementName=thisControl}"></local:SomeDataControl>
</local:CustomControl1.ItemsCollection>
</local:CustomControl1>
一切都很好,直到我想将 DVal1,2 和 3 绑定到特定项目。它们都具有默认值。 我已经寻找了 3 天的答案,但我找不到任何有帮助的东西。我还尝试对集合使用 DependenyProperty,或者将其类型更改为一个简单的列表,也是 Freezable,但没有任何帮助。
我真的很想在 XAML 中以这种方式声明我的组,而不是将所有内容放在我的 ViewModel 中以达到布局。
任何形式的帮助都会很棒。
提前谢谢你。
【问题讨论】:
-
在调试模式下运行它并观察输出窗口是否有绑定错误
-
感谢您的提示,实际上它帮助了很多。
标签: c# wpf binding viewmodel itemscontrol