在数据绑定方面,我觉得我错过了WPF的一个相当基本的概念,但我似乎找不到谷歌关键词的正确组合来定位我想要的内容,所以so社区可能会有所帮助。:)
我有一个WPF用户控件,它需要数据绑定到两个独立的对象才能正确显示。两个对象都必须从外部源动态设置。到目前为止,我只是使用表单的DataContext属性进行动态对象绑定,但这只允许引用一个对象。我觉得这是一个简单的问题,我一定错过了一些显而易见的东西。
我之前的尝试看起来像这样:
<UserControl.Resources>
<src:Person x:Key="personSource" />
<src:Job x:Key="jobSource" />
</UserControl.Resources>
<TextBox Text="{Binding Source={StaticResource personSource}, Path=Name" />
<TextBox Text="{Binding Source={StaticResource jobSource}, Path=Address" />
这将绑定到我给类的任何默认值,但如果我尝试在代码中动态设置对象(如下所示),我看不到任何更改。
Person personSource = FindResource("personSource") as Person;
personSource = externalPerson;
Job jobSource= FindResource("jobSource") as Job;
jobSource = externalJob;
我错过了什么?
我可能会使用带有两个DependencyProperty的CustomControl。然后,使用自定义控件的外部网站可以将他们想要的数据绑定到该控件,也可以通过使用自定义控件来模板化控件在不同情况下的外观。
自定义控制代码看起来像:
public class CustomControl : Control
{
public static readonly DependencyProperty PersonProperty =
DependencyProperty.Register("Person", typeof(Person), typeof(CustomControl), new UIPropertyMetadata(null));
public Person Person
{
get { return (Person) GetValue(PersonProperty); }
set { SetValue(PersonProperty, value); }
}
public static readonly DependencyProperty JobProperty =
DependencyProperty.Register("Job", typeof(Job), typeof(CustomControl), new UIPropertyMetadata(null));
public Job Job
{
get { return (Job) GetValue(JobProperty); }
set { SetValue(JobProperty, value); }
}
static CustomControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl), new FrameworkPropertyMetadata(typeof(CustomControl)));
}
}
Generic.xaml是一个应该为您创建的文件,并且可能具有如下样式:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication3">
<Style TargetType="{x:Type local:CustomControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomControl}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<StackPanel>
<TextBox Text="{TemplateBinding Person.Name}" />
<TextBox Text="{TemplateBinding Job.Address}" />
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
最后,当你使用你的控制时,你会做这样的事情。
<src:CustomControl Person="{Binding Person}" Job="{Binding Job}" />
文本框不更新的原因是您将它们绑定到StaticResource。顾名思义,这些资源是静态的,不会发布更改通知。因为Binding是MarkupExtension,并且不是从DependencyObject派生的,所以不能使用DynamicResource。
尝试在控件上创建depedency属性以引用Person和Job对象。
然后将UserControl的DataContext设置为引用它自己。
DataContext="{Binding RelativeSource={RelativeSource Self}}"
然后可以使用点表示法来引用所需的属性。
<TextBox Text="{Binding Path=Person.Name" />
<TextBox Text="{Binding Path=Job.Address" />
或者使用源参数
<TextBox Text="{Binding Source=Person, Path=Name" />
<TextBox Text="{Binding Source=Job, Path=Address" />