Вложенное связывание пользовательских элементов управления - PullRequest
1 голос
/ 15 февраля 2010

У меня возникли проблемы с выполнением следующего сценария (этот код не является действительным кодом, но принципы те же. В основном мне нужно передать значение из MainPage вниз во вложенный «многоразовый пользовательский элемент управления», который связывает к его собственным свойствам. Я хочу видеть текст «Вот оно!» на экране, но он не устанавливается в элементе управления SilverlightControl2 (я подозреваю, что из-за настройки DataContext) - но я как это исправить?

MainPage.xaml

<Grid>
    <ContentPresenter>
        <ContentPresenter.Content>
            <Local:SilverlightControl1 OneValue="This is it!"/>
        </ContentPresenter.Content>
    </ContentPresenter>
</Grid>

SilverlightControl1.xaml

<Grid>
    <Local:SilverlightControl2 TwoValue="{Binding OneValue}"/>
</Grid>

SilverlightControl1.xaml.cs

public partial class SilverlightControl1 : UserControl
{
    public string OneValue
    {
        get { return (string)GetValue(OneValueProperty); }
        set { SetValue(OneValueProperty, value); }
    }

    public static readonly DependencyProperty OneValueProperty = DependencyProperty.Register(
        "OneValue", typeof(string), typeof(SilverlightControl1), new PropertyMetadata(string.Empty));

    public SilverlightControl1()
    {
        InitializeComponent();
        this.DataContext = this;
    }
}

SilverlightControl2.xaml

<Grid x:Name="LayoutRoot" Background="White">
    <TextBlock Text="{Binding TwoValue}"  Foreground="Blue" />
</Grid>

SilverlightControl2.xaml.cs

public partial class SilverlightControl2 : UserControl
{
    public string TwoValue
    {
        get { return (string)GetValue(TwoValueProperty); }
        set { SetValue(TwoValueProperty, value); }
    }

    public static readonly DependencyProperty TwoValueProperty = DependencyProperty.Register(
        "TwoValue", typeof(string), typeof(SilverlightControl2), new PropertyMetadata(string.Empty));


    public SilverlightControl2()
    {
        InitializeComponent();
        this.DataContext = this;
    }
}

1 Ответ

1 голос
/ 15 февраля 2010

Как только вы почувствуете необходимость сделать это: -

this.DataContext = this; 

знаю, что вы, вероятно, ошиблись. Это, вероятно, первое, что я ожидал найти в Silverlight "списке неприятных запахов".

В этом случае, когда вы специализируетесь UserControl, лучше сделать следующее: -

SilverlightControl1.xaml

<Grid>         
    <Local:SilverlightControl2 x:Name="MyControl2" />         
</Grid>

SilverlightControl1.xaml.cs (я просто показываю конструктор остальное, как у вас)

public SilverlightControl1()  
{  
    InitializeComponent();  
    MyControl2.SetBinding(SilverlightControl2.TwoValueProperty , new Binding("OneValue") { Source = this });

} 

SilverlightControl2.xaml

<Grid x:Name="LayoutRoot" Background="White">               
    <TextBlock x:Name="MyTextBox"  Foreground="Blue" />               
</Grid> 

SilverlightControl1.xaml.cs (я просто показываю конструктор остальное, как у вас)

public SilverlightControl2()  
{  
    InitializeComponent();  
    MyTextBox.SetBinding(TextBox.TextProperty , new Binding("TwoValue") { Source = this });  
} 

Поскольку в UserControls вы знаете структуру XAML и можете называть элементы, к которым вам нужен доступ, в коде, вы можете создать привязку, используя вместо этого строку кода. Это оставляет DataContext свободным для выполнения того, для чего он предназначен, вместо того, чтобы использовать его для других целей.

Альтернативный подход, где вместо специализации UserControl вы создаете шаблонный элемент управления, в этом случае привязка может быть выражена в XAML с использованием чего-то вроде: -

<TextBox Text="{TemplateBinding TwoValue}" />

Привязка к шаблону работает только в ControlTemplate, поэтому вы не можете использовать его в UserControl.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...