Как добиться DataBinding кода за элементом? - PullRequest
2 голосов
/ 27 февраля 2012

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

.cs

public partial class ChimeraUserControl : UserControl
{   
    private ChimeraViewModel Chimera { get; set; }

    public ChimeraUserControl(Chimera chimera)
    {
        this.Chimera = new ChimeraViewModel(chimera);
        InitializeComponent();
    }
}

Я хочу быть в состоянии сделать две вещи: при использовании этого пользовательского элемента управления, чтобы иметь возможность отправлять Chimera через привязку, а также, чтобы все тексты и другие элементы были связаны с этим Chimera , Я много искал, но не нашел ничего, что меня устраивало.

Что вы, ребята, думаете?

То, что я уже пытался прочитать:

http://dev -for-fun.blogspot.com / 2008/06 / МОФ-пример-создание-UserControl-and.html

Привязка модели представления к модели представления дочернего пользовательского элемента управления в Silverlight? 2 источника - 1 цель

И много других страниц, но ни одна не казалась достаточно простой, и, взломав ее коды, я не нашел решения своей проблемы.

Ответы [ 2 ]

4 голосов
/ 27 февраля 2012

Во-первых, сделайте Chimera Свойство зависимости , чтобы оно могло участвовать в системе привязки

public static readonly DependencyProperty ChimeraProperty = 
    DependencyProperty.Register("Chimera ", typeof(ChimeraViewModel), 
    typeof(ChimeraUserControl), new FrameworkPropertyMetadata(null));

public ChimeraViewModel Chimera 
{
    get { return (ChimeraViewModel)GetValue(ChimeraProperty ); }
    set { SetValue(ChimeraProperty, value); }
}

Во-вторых, вы можете ссылаться на ваше свойство Chimeria через RelativeSource или ElementName привязка

<UserControl x:Name="ChimeraViewRoot" ... >

    <StackPanel>
        <!-- ElementName Binding -->
        <TextBlock Text="{Binding ElementName=ChimeraViewRoot, Path=Chimeria.Name}" />

        <!-- RelativeSource Binding -->
        <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:ChimeraView}}, Path=Chimeria.Name}" />

    </StackPanel>
</UserControl>

Вы также можете просто установить DataContext элементов управления внутри UserControl в свойство Chimera, чтобы сделать синтаксис очистки более чистым

<UserControl x:Name="ChimeraViewRoot" ... >
    <StackPanel DataContext="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:ChimeraView}}, Path=Chimeria}" >

        <TextBlock Text="{Binding Name}" />
        <TextBlock Text="{Binding Description}" />

    </StackPanel>
</UserControl>

Я обычно не предлагаю определять UserControl.DataContext в вашем UserControl, потому что это значение должно быть передано из того, что использует UserControl.Установка внутри UserControl может позже вызвать путаницу, когда вы пытаетесь выяснить, почему определенный UserControl не работает с ожидаемым DataContext.

Лично, когда я создаю ViewModel, который должен идти с определенным UserControl, я предпочитаю установить DataTemplate в приложении, чтобы все экземпляры моего ViewModel рисовались с моим пользовательским UserControl.Это означает, что я предполагаю, что UserControl.DataContext всегда будет иметь определенный ViewModel тип

<DataTemplate DataType="{x:Type local:ChimeriaViewModel}">
    <local:ChimeriaView /> <!-- DataContext will always be ChimeriaViewModel -->
</DataTemplate>

. Это будет неявно использовать ChimeriaView всякий раз, когда Визуальное Дерево встречает объект типа ChimeriaViewMmodel.

Например, следующий код отобразит StackPanel, заполненный ChimeriaView объектами

<ItemsControl ItemsSource="{Binding MyListOfChimeriaViewModels}" />

Или для отображения одного объекта я обычно буду использовать что-то вроде ContentControl

<!-- Will get drawn using ChimeriaView due to DataTemplate defined above -->
<ContentControl Content="{Binding MyChimeriaViewModelProperty}" />

Кроме того, зная, что DataContext для ChimeriaView будет объектом типа ChimeriaViewModel, я бы избавился от DependencyProperty в целом

<UserControl>
    <StackPanel>
        <!-- I know the DataContext is ChimeriaViewModel -->
        <TextBlock Text="{Binding Name}" />
        <TextBlock Text="{Binding Description}" />

    </StackPanel>
</UserControl>
0 голосов
/ 27 февраля 2012

Я могу предложить следующие вещи из того, что я могу понять из вашего квеста.

  1. Вы должны сделать это пользовательским элементом управления вместо UserControl.

    Для получения справки просмотрите следующие ссылки -

    Обзор авторизации управления

    http://www.codeproject.com/Articles/49802/Create-a-WPF-Custom-Control-Part-2

  2. Сделать Chimera a DependencyProperty для поддержки Binding (как объяснено в ссылке SO, которую вы добавили и над статьями).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...