1

I have some problems with a WPF custom control, I'm trying to make it work but just don't get it:

Here is my problem, I'm creating a simple custom control that's almost the same to a TextBox. This control has a dependency property named "Texto", and the binding between the XAML and back-code of the custom control works fine, here is the code:

<UserControl x:Class="WpfCustomControlLibrary1.UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="47" d:DesignWidth="147">
<Grid Height="43" Width="142">
    <TextBox Height="23" HorizontalAlignment="Left" Margin="12,8,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" Text="{Binding Texto}"/>        
</Grid>

And the dependency property code:

public static readonly DependencyProperty TextoProperty = DependencyProperty.Register("Texto", typeof(string), typeof(UserControl1));

    public string Texto
    {
        get
        {
            return (string)GetValue(TextoProperty);
        }

        set
        {
            SetValue(TextoProperty, value);
        }
    }

Ok, now the problem: When I use this control in other windows I try to bind the "Texto" property to a viewmodel (as simple as everything else) but the property on the view model just dont change:

The ViewModel code:

 public class ViewModelTest
{
    public string SomeText { get; set; }
}

And the code of the applicatoin Window:

public ViewModelTest test;

    public Window1()
    {
        InitializeComponent();
    }        

    private void button1_Click_1(object sender, RoutedEventArgs e)
    {
        MessageBox.Show(test.SomeText);
        MessageBox.Show(uc.Texto);
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        test = new ViewModelTest();
        this.DataContext = test;
    }

And the binding with the property of the view model:

<my:UserControl1 HorizontalAlignment="Left" Margin="27,12,0,0" Name="uc" VerticalAlignment="Top" Texto="{Binding Path=SomeText,Mode=TwoWay}"/>

Just for make it clearer, if I write "Hello" in the custom control and then I push the "button1", the first message shows nothing and the second message shows "Hello".

As you can see I'm fairly new into this, so I hope some of you can help me. Thanks.

4

1 回答 1

2

Your binding Texto="{Binding SomeText}" works fine, the problem is the rebinding from your user control to the inner textbox. Remember binding will ALWAYS, if not modified, refere to the DataContext. But your DataContext doesn't contain the property Texto. Your control has that, To refere to that you need something called TemplateBinding, but this only works when you are in a ControlTemplate. Which you aren't so what is the solution? You can use a special form of binding, by changing the source from the DataContext to a control with a given name: First give your UserControl a name

<UserControl x:Class="WpfCustomControlLibrary1.UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         x:Name="mainControl"
         d:DesignHeight="47" d:DesignWidth="147">

and now change the binding to refere to the control, not the DataContext of the control anymore.

 <TextBox Text="{Binding ElementName=mainControl, Path=Texto}"/>

Now your ViewModel binds to your user control and the content of the user control binds to the user controls Texto property.

Also one minor thing, what you called custom control, is in fact a user control, custom controls are something else.

于 2013-01-31T16:47:48.493 回答