Я чувствую, что мне не хватает довольно фундаментальной концепции 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;
Что мне не хватает?





Я бы, вероятно, использовал 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}" />
Не могли бы вы подробнее рассказать о том, как вы сейчас пытаетесь это сделать? Возможно, создайте новый вопрос, если он больше не актуален.
Хорошо, я решил это. И этот, и ответы Яна Оукса вместе - вот что решило эту проблему для меня, но, поскольку этот имеет более явный код, ответ идет к Тодду.
Причина, по которой ваши текстовые поля не обновляются, заключается в том, что вы привязываете их к 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" />
Кажется, это сработает, но теперь у меня другая проблема. Я действительно не хочу использовать стили для привязки этих элементов, но всякий раз, когда я пытаюсь сослаться на новое свойство зависимости, оно пытается найти его в тексте данных, а не в моем локальном объекте. Как я могу явно сослаться на локальное свойство?