locked
Correct use of Blend and Databinding in a Usercontrol in Silverlight 3 RRS feed

  • Question

  • Hi,
      I have created a small UserControl that contains a text box and a text block. I then created two properties in the code behind and used data binding to hook them to the Text/Content of the textbox and textblock. I can get this to work as I want, but I feel like I'm fighting the tools - which makes me wonder if I'm not doing this the "best" way.

      First, here is the code-behind:

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.ComponentModel;
    
    namespace System8ToyMC
    {
    	public partial class NamedValue : UserControl
    	{
    		public NamedValue()
    		{
    			// Required to initialize variables
    			InitializeComponent();
                LayoutRoot.DataContext = this;
    		}
    
            [Category("Numbers")]
            [Description("The name of the property we are looking at")]
            public string ValueName
            {
                get { return (string)GetValue(ValueNameProperty); }
                set { SetValue(ValueNameProperty, value); }
            }
    
            // Using a DependencyProperty as the backing store for ValueName.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty ValueNameProperty =
                DependencyProperty.Register("ValueName", typeof(string), typeof(NamedValue), new PropertyMetadata("b Jets:"));
    
            [Category("Numbers")]
            [Description("The value of the property to show")]
            public double Value
            {
                get { return (double)GetValue(ValueProperty); }
                set { SetValue(ValueProperty, value); }
            }
    
            // Using a DependencyProperty as the backing store for Value.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty ValueProperty =
                DependencyProperty.Register("Value", typeof(double), typeof(NamedValue), new PropertyMetadata(0.45));
    
    
    	}
    }
    <UserControl
    	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:Class="System8ToyMC.NamedValue"
    	d:DesignWidth="160" d:DesignHeight="56">
    
    	<StackPanel x:Name="LayoutRoot" Orientation="Horizontal">
    		<TextBlock Text="{Binding ValueName, Mode=OneWay}" TextWrapping="Wrap" Name="TBValueName" />
    		<TextBox TextWrapping="Wrap" Width="100" Text="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=Default}" Name="TBValue" />
    	</StackPanel>
    </UserControl>
    Here are the two issues I've got:

    First, when I do the layout of these controls in Blend 3 it would be very nice to have some sample data associated with the TextBox and TextBlock. You'll note that I create the dependency properties with initial values. However, Blend shows none of this data in its UI - which makes it rather hard to design this correctly! What is the standard thing people do here?

    Second comes when it is time to wire up my TextBox and TextBlock in Blend to those dependency properties. When I bring up the Blend 3 databinding dialog the tabs associated with "Explicit Data Context" and "Data Field" are both empty. If I look at the "Element Property" tab I can select the UserControl, scroll down and find my "ValueName" or "Value" property and make the binding. But this causes Blend to name the UserControl. That isn't all that good an idea, is it? I ask because Blend starts giving me errors and warnings about "more than one object named UserControl on the same surface" (or similar). Blend doesn't seem to recognize the data-context I set in my code... and should I even be doing it there? Is there a Binding expression that is better suited to this situation?

    Heck - should I even be using dependency properties? What is the best way to accomplish this?

    Many thanks for advice!

    Cheers,
      Gordon.

    P.S. I'm using Blend 3, VS 2010 for this particular example.
    Gordon
    Saturday, September 26, 2009 11:05 PM

All replies

  • Hi Gordon,

    What you have here is a perfect use case (and I would do it the same way) of encapsulating visual + functionality as properties.

    The warning is a result of an unfortunately limitation in Silverlight, that we hope will be addressed in the Silverlight 4 timeframe. Till then, you should continue to setup the DataContext in code behind if you intended to use the UserControl instance in multiple places (as the warning indicates correctly).

    About visualizations - you can easily use the Blend sample data system to setup visualization for this databinding like so:

    a) Create a new sample data source
    b) Use the menu associated with the sample data source to disable sample data in the running application (as the data would come from the code-behind association that you are setting up in the running application)
    c) Delete the default collection that we create for you
    d) Add a new property can rename it to Value
    e) Drag and drop the sample data source root object onto the root grid.

    Hope this works!

    thanks,
    Unni
    This posting is provided "AS IS" with no warranties, and confers no rights.
    Sunday, September 27, 2009 8:00 PM
  • Hi,
      Thanks for the help! I'll continue to add LayoutRoot.DataContext = this to the header of all my objects, then. Other user controls use this user control and typically contain 4 or 5 instances of this control.

      The data source thing worked first time - very nice! I need a little more flexability, however, in the types of data it generates. For example, for an example string I'd like to use something like "b eff:" - everything in there seems to generate things that are fairly wrong.

      Also, on some of my other objects take a reasonably complex object - for example, something that looks like (as far as data-binding is concerned):

    class FlavorSample
    {
      public double Bottom {get; set;}
      public double Charm {get; set;}
      public double Light {get; set;}
      public double LightCharm {get; set;}
      public double Total {get; set;}
    }

    Ahhh - I see - :-) I just create a complex property! Very nice! Ok -- thanks a lot for your help!

      Cheers,
        Gordon.
    Gordon
    Tuesday, September 29, 2009 1:44 PM