locked
WinRT XAML User Control property not working when using data bindings RRS feed

  • Question

  • I have a simple user control with a single property called "Title".  When using the user control and assigning directly to the property, the text will appear, but when using Data Binding, it will not.

    Here is the user control XAML:

    <UserControl
        x:Class="UserControlTest.UserControl1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    
        <Grid>
            <TextBlock Text="{Binding Title}" FontSize="30"/>
        </Grid>
    </UserControl>

    The code behind for the user control:

    public sealed partial class UserControl1 : UserControl
        {
            public UserControl1()
            {
                this.InitializeComponent();
                DataContext = this;
            }
    
    
            public string Title
            {
                get { return (string)GetValue(TitleProperty); }
                set { SetValue(TitleProperty, value); }
            }
    
            public static readonly DependencyProperty TitleProperty =
                DependencyProperty.Register("Title", typeof(string), typeof(UserControl1), new PropertyMetadata(null));
        }

    To use the user control I have a simple view model:  

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace UserControlTest
    {
        public class BlankPageViewModel : INotifyPropertyChanged
        {
            public BlankPageViewModel() 
            { 
                Title2 = "This doesn't work :-(";
                ControlStatement = "But this does...";
            }
    
            private string _Title2;
            public string Title2
            {
                get { return _Title2; }
                set
                {
                    _Title2 = value;
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("Title2"));
                }
            }
    
            private string _ControlStatement;
            public string ControlStatement
            {
                get { return _ControlStatement; }
                set
                {
                    _ControlStatement = value;
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("ControlStatement"));
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
        }
    }

    Here is a page where I use the control. I also added a 'ControlStatement' to ensure the ViewModel was correctly bound:

    <Page x:Class="UserControlTest.BlankPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:UserControlTest"> <Page.DataContext> <Binding> <Binding.Source> <local:BlankPageViewModel /> </Binding.Source> </Binding> </Page.DataContext> <StackPanel>
    <!-- This works OK -->
    <local:UserControl1 Title="This Works!"/>
    <!-- This doesn't work -->
            <local:UserControl1 Title="{Binding Title2}"/>
    <!-- This works too! -->
    <TextBlock Text="{Binding ControlStatement}" FontSize="30" /> </StackPanel> </Page>

    The resulting output is that the 'This Works' shows up.
    From the ViewModel binding the control statement 'But this does' shows up.
    But the 'This Doesn't Work' from the Title property of the ViewModel doesn't show up.

    I need to create a more complex control, but I'm trying to get this simple sample to work before I proceed. 



    Friday, April 20, 2012 5:42 PM

Answers

  • Hi William,

    After removing "DataContext = this;", please also change the binding on the TextBlock to the following code so it can still bind to the UserControl.

    <UserControl
        x:Class="UserControlTest.UserControl1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Name="uc">
    
        <Grid>
            <TextBlock Text="{Binding Path=Title,ElementName=uc}" FontSize="30"/>
        </Grid>
    </UserControl>

    Best regards,

    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us

    • Marked as answer by William Stuart Wednesday, April 25, 2012 8:10 PM
    Tuesday, April 24, 2012 1:24 AM
    Moderator

All replies

  • Hi William Stuart,

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

    Since you explicitly set DataContext to the UserControl itself, it will no long inherits DataContext from its parent. So the data binding doesn't work.

    Remove "DataContext = this;" and your code would work fine.

    Best regards,


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us

    Monday, April 23, 2012 2:28 AM
    Moderator
  • Hello Min,

    Thank you for your prompt response.  I removed the 'DataContext = this;' as suggested.  Because I used the term Title as both a dependency property in the user control and the binding property on the view model, it had a bit of an unexpected result.  I've updated the property I'm binding to in the view model above to be Title2 instead of Title.  Now in both the scenarios (data binding and setting the Title property directly) nothing shows up.  Is there an issue with the binding syntax of the TextBlock inside the user control?

    Thank you for your help,

    William

    Monday, April 23, 2012 6:18 PM
  • Hi William,

    After removing "DataContext = this;", please also change the binding on the TextBlock to the following code so it can still bind to the UserControl.

    <UserControl
        x:Class="UserControlTest.UserControl1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Name="uc">
    
        <Grid>
            <TextBlock Text="{Binding Path=Title,ElementName=uc}" FontSize="30"/>
        </Grid>
    </UserControl>

    Best regards,

    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us

    • Marked as answer by William Stuart Wednesday, April 25, 2012 8:10 PM
    Tuesday, April 24, 2012 1:24 AM
    Moderator
  • That worked, a combination of removing the this.DataContext = this from the code behind, adding the x:Name="uc" and ElementName="uc" corrected the problem.  It now works in all situations. Thank you!
    Wednesday, April 25, 2012 8:11 PM
  • I am able to bind in my UserControl but its not displaying. I have a Frame in which there are some UI elements. In that there is an item on tapping on which I need to bind some values in UserControl and then display it. When I debugged the code, I found that in UserControl, the values are bind but the UserControl is not displayed. I even tried using Dispatcher, but it did not help.
    Monday, March 16, 2015 9:14 AM