locked
Binding problem with UserControl / Parent DataContext access failure ?

    Question

  • Hello together,
    I use a UserControl within the MainPage and a Data object bound to the DataContext of the MainPage.

    If I use such an object for data binding:

    public class UCData
    {
        public string Text { get; set; }
    }

    it works fine.
    If I use such an object for data binding:

    public class MainPageData
    {
        private UCData _UCData = new UCData() { Text = "Hello B" };
        public UCData UCData
        {
            get { return _UCData; }
            set { _UCData = value; }
        }
        public string Text2 { get; set; }
    }

    There is no access to the Text string.

    Thank you for your help.
    Regards
    Torsten

    Code:

    public class UCData
    {
        public string Text { get; set; }
    }

    public class MainPageData
    {
        private UCData _UCData = new UCData() { Text = "Hello B" };
        public UCData UCData
        {
            get { return _UCData; }
            set { _UCData = value; }
        }
        public string Text2 { get; set; }
    }

    public sealed partial class UC : UserControl
    {
        public UC()
        {
            this.InitializeComponent();
        }

        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(UC), new PropertyMetadata(null));

        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }
    }

    <UserControl
        x:Class="TestUC.UC"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:TestUC"
        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>
            <TextBlock FontSize="20" Text="{Binding Text}" Margin="20,100,0,0" HorizontalAlignment="Center"/>
        </Grid>
    </UserControl>

    MainPage.xaml.cs :

    private void Page_Loaded(object sender, RoutedEventArgs e)
    {
        // Bind the UCData object to the DataContext
        //UCData uCData = new UCData();
        //uCData.Text = "Hello A";
        //this.DataContext = uCData;

        // Bind the MainPageData object to the DataContext
        MainPageData mainPageData = new MainPageData();
        mainPageData.Text2 = "Bye B";
        this.DataContext = mainPageData;
    }

    <Page
        x:Class="TestUC.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:TestUC"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" Loaded="Page_Loaded">

        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
            <!--local:UC Text="{Binding Text}" Margin="100,100,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/-->
            <local:UC Text="{Binding UCData.Text}" Margin="100,100,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
            <TextBlock FontSize="20" Text="{Binding Text2}" Margin="100,200,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
        </Grid>
    </Page>

    Tuesday, November 11, 2014 1:05 PM

Answers

  • You must set the DataContext of the TextBlock in the UC to the UC itself for the text to show up in the TextBlock.

    In XAML using an ElementName source (remember to also set the x:Name attribute of the UC):

    <UserControl
         x:Class="TestUC.UC"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="using:TestUC"
         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" x:Name="uc">
         <Grid>
             <TextBlock FontSize="20" Text="{Binding Text, ElementName=uc}" Margin="20,100,0,0" HorizontalAlignment="Center"/>
         </Grid>
     </UserControl>

    or in code:

    <UserControl
         x:Class="TestUC.UC"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="using:TestUC"
         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>
             <TextBlock x:Name="tb" FontSize="20" Text="{Binding Text}" Margin="20,100,0,0" HorizontalAlignment="Center"/>
         </Grid>
     </UserControl>

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

     

     Please remember to mark helpful posts as answer and/or helpful.

    • Marked as answer by Torsten Menzel Tuesday, November 11, 2014 6:15 PM
    Tuesday, November 11, 2014 4:53 PM

All replies

  • You must set the DataContext of the TextBlock in the UC to the UC itself for the text to show up in the TextBlock.

    In XAML using an ElementName source (remember to also set the x:Name attribute of the UC):

    <UserControl
         x:Class="TestUC.UC"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="using:TestUC"
         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" x:Name="uc">
         <Grid>
             <TextBlock FontSize="20" Text="{Binding Text, ElementName=uc}" Margin="20,100,0,0" HorizontalAlignment="Center"/>
         </Grid>
     </UserControl>

    or in code:

    <UserControl
         x:Class="TestUC.UC"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="using:TestUC"
         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>
             <TextBlock x:Name="tb" FontSize="20" Text="{Binding Text}" Margin="20,100,0,0" HorizontalAlignment="Center"/>
         </Grid>
     </UserControl>

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

     

     Please remember to mark helpful posts as answer and/or helpful.

    • Marked as answer by Torsten Menzel Tuesday, November 11, 2014 6:15 PM
    Tuesday, November 11, 2014 4:53 PM
  • Hello together,

    Conversely, it must be.

    This version works also correctly without x:Name="uc" and ElementName=uc :

    UserControl:

    <TextBlock FontSize="20" Text="{Binding UCData.Text}" Margin="20,100,0,0" HorizontalAlignment="Center"/>

    MainPage:

    <local:UC Text="{Binding UCData}" Margin="100,100,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>

    Thanks Magnus for your help.

    Regards
    Torsten


    Tuesday, November 11, 2014 6:14 PM