Silverlight:绑定到UserControl的依赖项属性

时间:2011-04-04 10:40:22

标签: silverlight-4.0 binding dependency-properties

我有一个名为GraphPanel的用户控件。它有两个依赖项属性,一个是自定义,PanelTitle,另一个是继承自FrameworkElement,Content。

    public static readonly DependencyProperty PanelTitleProperty = DependencyProperty.Register(
        "PanelTitle",
        typeof(string),
        typeof(GraphPanel),
        new PropertyMetadata("")
    );
    // ...
    public string PanelTitle
    {
        set { SetValue(PanelTitleProperty, value); } 
        get { return (string)GetValue(PanelTitleProperty); }
    }

XAML代码如下:

<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>

运行它会产生异常:

Value does not fall within the expected range.
   at MS.Internal.XcpImports.CheckHResult(UInt32 hr)

我做错了什么?我该怎么做才能实现这种绑定?

谢谢!

1 个答案:

答案 0 :(得分:0)

我通过从ContentPresenter中删除绑定来解决此问题。也就是说,这个解决方案存在缺陷,因为自定义控件不是元素容器。

通过创建一个扩展ContentControl的新类,使用ControlTemplate进行样式设计,无需复杂的绑定方案即可实现。

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);
    }
}

和XAML代码:

<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>

有时它只是帮助写下来,你会发现自己的错误。谢谢你给了这个片刻的想法!