Двухстороннее связывание с UserControl - PullRequest
3 голосов
/ 12 августа 2010

Я пытаюсь установить привязку twoway к созданному мною UserControl.

Когда я использую элемент управления в Xaml, устанавливается DataContext следующим образом ...

<uc:MyUserControl DataContext="{Binding Path=MyObject, Mode=TwoWay}" />

Myпользовательский элемент управления определяется следующим образом ....

<UserControl x:Class="SilverlightApplication1.XText"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <TextBox x:Name="Text" Text="{Binding}"/>

    </Grid>
</UserControl>

Данные отображаются корректно, однако, если я изменю их, я хочу обновить их с привязкой TwoWay.

Я пыталсяэто ниже, но это ошибки во время выполнения, так как путь не определен.

    <Grid x:Name="LayoutRoot" Background="White">
        <TextBox x:Name="Text" Text="{Binding Mode=TwoWay}"/>

    </Grid>
</UserControl>

Любые идеи о том, как заставить элемент управления внутри usercontrol связать twoway с DataContext?

Ответы [ 3 ]

2 голосов
/ 12 августа 2010

Хотя ваш ответ выше (с автоответчиком), похоже, решает проблему, я не могу не думать, что это проблема проблемной области.Мне трудно подумать , почему вы бы хотели связать напрямую, в первую очередь, так как это дает вам меньше контроля над тем, что происходит с данными.

Примите следующее:

<UserControl 
    x:Class="SilverlightApplication1.XText"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    x:Name="UserControl"
    d:DesignHeight="300" 
    d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <TextBox x:Name="Text" Text="{Binding Path=Value, ElementName=UserControl, Mode=TwoWay}"/>    
    </Grid>
</UserControl>

Затем в коде:

public partial class XText
{
    public static DependencyProperty ValueProperty =
        DependencyProperty.Register(
            "Value",
            typeof(string),
            typeof(XText),
            new FrameworkPropertyMetadata(null)
        );

    public string Value
    {
        get { return ((string)(base.GetValue(XText.ValueProperty))); }
        set { base.SetValue(XText.ValueProperty, value); }
    }

    ...
}

Затем, когда вы будете готовы его использовать:

<uc:XText Value="{Binding Path=MyObject, Mode=TwoWay}" />

Да, это больше кода,но это дает вам гораздо больший контроль над тем, что происходит с Value внутри вашего UserControl, и значительно упрощает работу с этим кодом в будущем.

Мысли?

-Doug

EDIT: исправлено несколько опечаток.

1 голос
/ 23 августа 2010

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

Это сочетание моего первого ответа и ответа Дугаответ.Обратите внимание, что в UserControl отсутствует свойство name, а в TextBox отсутствует привязка, объявленная в XAML

XAML

<UserControl 
    x:Class="SilverlightApplication1.XText"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" 
    d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <TextBox x:Name="MyText"/>    
    </Grid>
</UserControl>

CodeBehind

public partial class XText
{
    public XText()
    {
       InitializeComponent();
       MyText.SetBinding(TextBox.TextProperty, new Binding() 
       { 
          Source = this,  
          Path = new PropertyPath("Value"), 
          Mode = BindingMode.TwoWay
       });
    }


    public static DependencyProperty ValueProperty =
        DependencyProperty.Register(
            "Value",
            typeof(string),
            typeof(XText),
            new PropertyMetadata(null)
        );

    public string Value
    {
        get { return ((string)(GetValue(ValueProperty))); }
        set { SetValue(ValueProperty, value); }
    }

    ...
}

Когда вы будете готовы использовать его, сделайте следующее

<uc:XText Value="{Binding Path=MyObject, Mode=TwoWay}" />
0 голосов
/ 12 августа 2010

Хорошо, я думаю, что нашел способ заставить это работать ....

Сначала я установил публичное свойство в коде моего UserControl за ...

public Binding BindingValue
{
   set { this.MyTextBox.SetBinding(TextBox.TextProperty, value); }
}

Тогда в XAML

<uc:MyUserControl BindingValue="{Binding Path=MyObject, Mode=TwoWay}" />
...