Unable to bind dependency properties of a custom user control
I'm trying to create a legend control that is a databound set of stack panels and am having significant issues with getting data binding to work. After many searches I was able to get binding to work on a standard control defined in my datatemplate. However, when I use exactly the same binding to set the value on my custom control, my dependency property doesn't get set. Here is the relevant XAML
EDIT I changed my complex custom item with a simple user control that just has a button - same effect - thanks for the help
<StackPanel x:Name="LayoutRoot" Background="Transparent">
<TextBlock Text="Legend:" />
<ItemsControl x:Name="tStack" ItemsSource="{Binding LegendItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Content="{Binding ItemLabel}" />
<pxsc:TestItem ItemLabel="{Binding ItemLabel}" />开发者_StackOverflow;
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- <pxsc:PXLegendItem ItemColor="Green" ItemLabel="TextLabel"/> -->
</StackPanel>
// TestItem
<UserControl x:Class="SilverlightControls.TestItem"
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"
d:DesignHeight="300" d:DesignWidth="400"
DataContext="{Binding RelativeSource={RelativeSource Self}}" >
<Grid x:Name="LayoutRoot" Background="White">
<Button Content="{Binding ItemLabel}" />
</Grid>
</UserControl>
TestItem code behind
public partial class TestItem : UserControl
{
public TestItem()
{
InitializeComponent();
}
#region ItemLabel
public static readonly DependencyProperty ItemLabelProperty =
DependencyProperty.Register("ItemLabel", typeof(string), typeof(TestItem),
new PropertyMetadata(new PropertyChangedCallback(OnItemLabelPropertyChanged)));
public string ItemLabel
{
get { return (string)GetValue(ItemLabelProperty); }
set { SetValue(ItemLabelProperty, value); }
}
private static void OnItemLabelPropertyChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
}
public static void SetItemLabel(DependencyObject obj, string val)
{
obj.SetValue(ItemLabelProperty, val);
}
public static double GetItemLabel(DependencyObject obj)
{
return (double)obj.GetValue(ItemLabelProperty);
}
#endregion
}
In my sample code, I populate LegendItems with 3 objects. The ItemsControl creates three buttons that are correctly labeled and three of my legenditem controls without any label set.
If I uncomment the last line I do see that the additional control correctly accepts the TextLabel value.
I thought this was a fairly "by-the-book" implementation so I'm surprised that it's not working and any assitance is gretly appreciated!
As a stab in the dark, you haven't implemented the ItemLabel
as a dependency property or if you have its not be implemented properly. If the latter then edit your question with the relevent code.
Edit
Since your control assigns itself to the DataContext
any existing DataContext
from its ancestors will be ignored. Remove your assignment to the DataContext
. Change your inner xaml to:-
<Grid x:Name="LayoutRoot" Background="White">
<Button Content="{Binding Parent.ItemLabel, ElementName=LayoutRoot}" />
</Grid>
That should get it working. BTW do you really need GetItemLabel
and SetItemLabel
static methods? Those are usually included for Attached properties but not standard dependency properties.
精彩评论