Click here to Skip to main content
15,881,938 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
I have a user control that has several dependency properties. I am databinding to them and all of them work except one. They are all strings with one of them being a list of strings. The list does not attach. I am using XAML Spy to dig in and see what the issue is. For all of the string SPs, it shows that they are being bound. It shows that the list is a local source. I used the exact same data binding on a combobox and it showed the list just fine.

Here are my DPs:
/// <summary>
    /// The _value contained in the ValueBox.
    /// Using a string because it can be cast to most other objects.
    /// </summary>
    public string Value
    {
      get { return (string)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(string), 
                                             typeof(ValueBox),
                                             new FrameworkPropertyMetadata
                                             { 
                                               DefaultValue = "",
                                               BindsTwoWayByDefault = true,
                                               DefaultUpdateSourceTrigger = System.Windows.Data.UpdateSourceTrigger.PropertyChanged
                                             });

    /// <summary>
    /// Type of _value contained by ValueBox.
    /// </summary>
    public string ValueType
    {
      get { return (string)GetValue(ValueTypeProperty); }
      set { SetValue(ValueTypeProperty, value); }
    }

    // Using a DependencyProperty as the backing store for ValueType.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ValueTypeProperty =
        DependencyProperty.Register("ValueType", typeof(string),
                                                 typeof(ValueBox),
                                                 new FrameworkPropertyMetadata
                                                 {
                                                   DefaultValue = "real",
                                                   DefaultUpdateSourceTrigger = System.Windows.Data.UpdateSourceTrigger.PropertyChanged
                                                 });

    /// <summary>
    /// Format the _value is to be displayed in.
    /// This only applies to numerical Valueboxes.
    /// </summary>
    
    public string ValueFormat
    {
      get { return (string)GetValue(ValueFormatProperty); }
      set { SetValue(ValueFormatProperty, value); }
    }

    // Using a DependencyProperty as the backing store for ValueFormat.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ValueFormatProperty =
        DependencyProperty.Register("ValueFormat", typeof(string),
                                                   typeof(ValueBox),
                                                   new FrameworkPropertyMetadata
                                                   {
                                                     DefaultValue = "{0:00.00000}",
                                                     DefaultUpdateSourceTrigger = System.Windows.Data.UpdateSourceTrigger.PropertyChanged,
                                                   });


public List<string> ValueList
    {
      get { return (List<string>)GetValue(ValueListProperty); }
      set { SetValue(ValueListProperty, value); }
    }

    // Using a DependencyProperty as the backing store for ValueList.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ValueListProperty =
        DependencyProperty.Register("ValueList", typeof(List<string>), 
                                                 typeof(ValueBox),
                                                 new FrameworkPropertyMetadata());


When I use the control in a sample app, the binding works fine

Here is the XAML snippet from my project:
XML
<ListBox Height="Auto" VerticalAlignment="Stretch" Width="Auto" Grid.Column="1" HorizontalContentAlignment="Stretch" Margin="0" Grid.ColumnSpan="2"
            		ItemsSource="{Binding DataContext.SelectedMoveToEdit.BuilderScriptVariables, ElementName=DataContextOwner}" ScrollViewer.VerticalScrollBarVisibility="Auto">
            		<ListBox.ItemTemplate>
            			<DataTemplate>
            				<Grid>
            					<Grid.ColumnDefinitions>
            						<ColumnDefinition Width="50*"/>
            						<ColumnDefinition Width="50*"/>
            					</Grid.ColumnDefinitions>
                      <ComboBox ItemsSource="{Binding OptionList}" Text="{Binding Label}" IsEditable="True"/>
                      <valuebox:ValueBox Value="{Binding Value}" 
                                         ValueType="{Binding ValueType}"
                                         ValueList="{Binding OptionList}"
                                         Caption="{Binding Name}"
                                         HorizontalAlignment="Stretch" Grid.Column="1"/>
            					<!--<TextBox Text="{Binding Value}" HorizontalAlignment="Stretch" Grid.Column="1"/>-->
            				</Grid>
            			</DataTemplate>
            		</ListBox.ItemTemplate>
            	</ListBox>


The line
ValueList="{Binding OptionList}"
is the one that is not connecting properly. All of the variables being bound are at the same level/depth in the same class. My sample app uses the exact same type of variable to bind to, but the user control is not inside a ListBox as it is in the real program. For the life of me, I can't understand what is different in my app than the sample app and why the other variables do not have a problem making the connection.

XAML Spy shows the Datacontext for the control having values in OptionList.

Any help or ideas are appreciated.

{FOLLOW UP}
I was able to get it working. I had the following code in the constructor for the user control:
public ValueBox()
    {
      InitializeComponent();

      this.SetValue(ValueListProperty, new List<string>()); 
    }


Commenting out the SetValue line allows my control to work in my project, but not in the sample project anymore. Without the line, I get ValueList not defined when I try setting values through XAML.

I think there is some kind of race happening when the control is initialized and sets the ValueList to a new list and when the databinding is happening. I could not figure what to check for or how to delay the databinding to allow both applications to use the same control.
Posted
Updated 30-Apr-13 7:11am
v2
Comments
stibee 3-May-13 21:30pm    
Can you show your BuilderScriptVariables class details please? Is inside this class an observable collection called "OptionList"?
Maybe can you also show how do you set the datacontext?
(Simples way is to show your whole view and viewmodel and also how you set datacontext..)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900