公开多个数据绑定源

时间:2008-11-04 17:48:57

标签: c# wpf data-binding

我觉得自己在数据绑定方面缺少一个相当基本的WPF概念,但我似乎无法找到正确的Google关键字组合来找到我所追求的内容,所以也许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;

我错过了什么?

2 个答案:

答案 0 :(得分:5)

我可能会使用带有两个DependencyProperties的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}" />

答案 1 :(得分:1)

您的文本框未更新的原因是您将它们绑定到StaticResource。顾名思义,这些资源是静态的,不发布更改通知。因为Binding是MarkupExtension并且不是从DependencyObject派生的,所以你不能使用DynamicResource。

尝试在控件上创建依赖属性以引用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" />