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:
public string Value
{
get { return (string)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(string),
typeof(ValueBox),
new FrameworkPropertyMetadata
{
DefaultValue = "",
BindsTwoWayByDefault = true,
DefaultUpdateSourceTrigger = System.Windows.Data.UpdateSourceTrigger.PropertyChanged
});
public string ValueType
{
get { return (string)GetValue(ValueTypeProperty); }
set { SetValue(ValueTypeProperty, value); }
}
public static readonly DependencyProperty ValueTypeProperty =
DependencyProperty.Register("ValueType", typeof(string),
typeof(ValueBox),
new FrameworkPropertyMetadata
{
DefaultValue = "real",
DefaultUpdateSourceTrigger = System.Windows.Data.UpdateSourceTrigger.PropertyChanged
});
public string ValueFormat
{
get { return (string)GetValue(ValueFormatProperty); }
set { SetValue(ValueFormatProperty, value); }
}
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); }
}
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:
<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"/>
</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.