开发者

Silverlight: Binding to UserControl's dependency properties

开发者 https://www.devze.com 2023-02-21 17:53 出处:网络
I have an user control named GraphPanel. It has two dependency properties, one custom, PanelTitle, and the other inherited from the FrameworkElement, Content.

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!

0

精彩评论

暂无评论...
验证码 换一张
取 消