使用UserControl进行TwoWay绑定

时间:2010-08-12 16:57:37

标签: c# silverlight xaml user-controls binding

我正在尝试在我创建的UserControl上设置twoway绑定。

当我在Xaml中使用控件时,设置DataContext就像这样......

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

我的用户控件定义如下....

<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绑定进行更新。

我在下面尝试了这个,但是由于没有定义Path,所以它在运行时出错。

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

    </Grid>
</UserControl>

关于如何让usercontrol中的控件双向绑定到DataContext的任何想法?

3 个答案:

答案 0 :(得分:2)

虽然您的上述(自我回答)答案似乎可以解决问题,但我不禁认为这是一个有问题的域名问题。我很难想到为什么你想要首先直接绑定,特别是因为它让你不太可能控制数据的发生。

采取以下措施:

<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}" />

是的,这是更多的代码,但它可以让您更好地控制ValueUserControl内部的情况,并且在将来更简单地使用此代码。

思想?

-Doug

编辑:解决了几个拼写错误。

答案 1 :(得分:1)

我找到了一个不需要你给基本控件命名的解决方案。 当我为基本UserControl定义一个名称时,我在向网格添加多个实例时为我创建了问题,因为它们被定义为相同的名称。

这是我的第一个答案和道格答案的结合。 请注意,UserControl缺少name属性,而TextBox没有在XAML

中声明的Binding

<强> 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>

<强>代码隐藏

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}" />

答案 2 :(得分:0)

好的,我想我已经想出办法让它发挥作用......

首先,我在UserControl的代码中设置了一个公共属性......

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

然后在XAML

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