Экспонирование нескольких источников привязки данных - PullRequest
4 голосов
/ 04 ноября 2008

Мне кажется, что я упускаю довольно фундаментальную концепцию WPF, когда речь идет о привязке данных, но я не могу найти правильную комбинацию ключевых слов Google, чтобы найти то, что мне нужно, поэтому, возможно, SO Community может Помогите. :)

У меня есть пользовательский элемент управления 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 ]

5 голосов
/ 04 ноября 2008

Я бы, вероятно, использовал CustomControl с двумя DependencyProperties. Тогда внешний сайт, который использует ваш пользовательский элемент управления, может привязать данные, которые они хотят, к этому элементу управления, также с помощью пользовательского элемента управления вы можете задать шаблон внешнего вида элемента управления в различных ситуациях.

Пользовательский код управления будет выглядеть примерно так:

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 голос
/ 04 ноября 2008

Причина, по которой ваши текстовые поля не обновляются, заключается в том, что вы привязываете их к StaticResource. Как следует из названия, эти ресурсы являются статическими и не публикуют уведомления об изменениях. А поскольку Binding является MarkupExtension и не является производным от объекта DependencyObject, вы не можете использовать DynamicResource.

Попробуйте создать свойства зависимостей в вашем элементе управления для ссылки на объекты Person и Job.

Затем установите DataContext из UserControl для ссылки на себя.

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" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...