I have an user control named GraphPanel. It has two dependency properties, one custom, PanelTitle, and the other inherited from the FrameworkElement, Content.
public static readonly DependencyProperty PanelTitleProperty = DependencyProperty.Register(
"PanelTitle",
typeof(string),
typeof(GraphPanel),
new PropertyMeta开发者_如何学JAVAdata("")
);
// ...
public string PanelTitle
{
set { SetValue(PanelTitleProperty, value); }
get { return (string)GetValue(PanelTitleProperty); }
}
The XAML code is as follows:
<UserControl
x:Class="PlaceringsGuiden.Library.Components.GraphPanel"
DataContext="{Binding RelativeSource={RelativeSource self}}">
<UserControl.Resources>
<ResourceDictionary Source="/App;component/Assets/Styles/GraphPanelStyles.xaml" />
</UserControl.Resources>
<Border Style="{StaticResource GraphPanelBorderStyle}">
<Grid Style="{StaticResource GraphPanelGridStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="8*" />
</Grid.RowDefinitions>
<Grid Grid.Column="0" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.02*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="0.02*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1"
Grid.Row="0"
Text="{Binding Path=PanelTitle}"
Style="{StaticResource GraphPanelHeaderStyle}" />
</Grid>
<Grid Grid.Column="0" Grid.Row="0" x:Name="GraphPanelContentPresenter">
<ContentPresenter Content="{Binding Path=Content}" />
</Grid>
</Grid>
</Border>
</UserControl>
Running this yields an exception:
Value does not fall within the expected range.
at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
What am I doing wrong? What should I do to achieve this binding?
Thanks!
I resolved this issue by removing the binding from the ContentPresenter. That said, this solution is flawed as the custom control is not an element container.
By creating a new class extending ContentControl, styling with ControlTemplate, is this achieved without the need of complicated binding scenarios.
public class GraphPanel : ContentControl
{
#region Properties
public string PanelTitle
{
get { return (string) GetValue(PanelTitleProperty); }
set { SetValue(PanelTitleProperty, value); }
}
#endregion
#region Dependency properties
public static readonly DependencyProperty PanelTitleProperty =
DependencyProperty.Register("PanelTitle", typeof(string), typeof(GraphPanel), new PropertyMetadata(""));
#endregion
public GraphPanel()
: base()
{
DefaultStyleKey = typeof(GraphPanel);
}
}
and XAML code:
<Style TargetType="local:GraphPanel">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:GraphPanel">
<Border Style="{StaticResource GraphPanelBorderStyle}">
<Grid Style="{StaticResource GraphPanelGridStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="8*" />
</Grid.RowDefinitions>
<Grid Grid.Column="0" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.02*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="0.02*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1"
Grid.Row="0"
Text="{TemplateBinding PanelTitle}"
Style="{StaticResource GraphPanelHeaderStyle}" />
</Grid>
<Grid Grid.Column="0" Grid.Row="1">
<ContentPresenter />
</Grid>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Sometimes it just helps writing it down, and you'd realise your own mistakes. Thanks for giving this a moment's thought though!
精彩评论