2010-08-12 70 views
3

我想在我创建的用户控件上设置双向绑定。用户控件双向绑定

当我使用在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绑定更新。

我已经在下面试过了,但是它在运行时出错,因为没有定义路径。

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

    </Grid> 
</UserControl> 

如何获得用户控件内部的控制,以双向绑定到DataContext任何想法?

回答

1

我发现了一个解决方案,并不要求您给出基本控件的名称。 当我为基础UserControl定义一个名称时,它在为我的Grid添加多个实例时为我创建了问题,因为它们被定义为相同的名称。

这是我的第一个答案和Doug的答案的结合。 注意的用户控件缺少名称属性和文本框在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> 

代码隐藏

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

MyText.SetBinding()块仍然有点黑客。我认为你会发现使用它比它的价值更多的问题。 – Doug 2010-08-24 15:43:30

0

好吧,我想我已经想出了一个办法来得到这个工作....

首先,我在设置在后面我的用户代码的公共属性...

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

然后XAML

<uc:MyUserControl BindingValue="{Binding Path=MyObject, Mode=TwoWay}" /> 
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}" /> 

是的,这是更多的代码,但它可以让你更好地控制UserControlValue发生的情况,并且使得这些代码在将来更加简单。

想法?

-Doug

编辑:修复了一对错别字。

+0

有趣的方法,让我试试。 – Gabe 2010-08-12 20:11:03

+0

我注意到的一件事是随机添加此用户控件到我的网格时出现错误。如果我正在使用这些用户控件中的一个,我会收到一个错误,指出“值不在预期的范围内”...如果我继续调试,则出现解析器错误,说“UserControl已存在于树中” UserControl就像你在上面所做的那样,这是否会造成问题?当我实际创建UserControl的实例时,我根本没有给它起个名字。但是就像你我在UserControl的实际Xaml中为它命名了UserControl,所以我可以使用ElementName绑定 – Gabe 2010-08-23 15:50:26

+0

我已经命名了我的所有UserControl并从未遇到过这个问题。当您命名您的UserControl时,它只属于控件本身的名称范围内。因此,当您在页面上多次使用相同的控件时,它不会命名冲突。我认为问题不在于我给你的代码,而是在你的实现中。 – Doug 2010-08-24 15:42:55