2012-01-15 48 views
0

当我创建了一个简单的用户控件工具提示:的UIElement零使用自定义的DependencyProperty

public partial class TooltipControl : UserControl 
{ 
    public static readonly DependencyProperty ToolTipControlContentProperty 
     = DependencyProperty.Register("ToolTipControlContent", typeof(FrameworkElement), typeof(TooltipControl), 
      new PropertyMetadata(new Grid())); 


    public static readonly DependencyProperty ToolTipProperty 
     = DependencyProperty.Register("ToolTip", typeof(string), typeof(TooltipControl), 
      new PropertyMetadata(string.Empty)); 

    public string Tooltip 
    { 
     get { return GetValue(ToolTipProperty) as string; } 
     set { SetValue(ToolTipProperty, value); } 
    } 

    public FrameworkElement ToolTipControlContent 
    { 
     get { return GetValue(ToolTipControlContentProperty) as FrameworkElement; } 
     set { SetValue(ToolTipControlContentProperty, value); } 
    } 

    public TooltipControl() 
    { 
     InitializeComponent(); 
    } 

} 

这是它的XAML:

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

    DataContext="{Binding RelativeSource={RelativeSource Self}}" 
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
    x:Class="Dashboard.Controls.TooltipControl" 
    mc:Ignorable="d" 
    d:DesignHeight="300" d:DesignWidth="400"> 

    <Grid x:Name="LayoutRoot" Width="150" Height="75"> 

     <Border Child="{Binding ToolTipControlContent}"> 
      <Border.Background> 
       <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0"> 
        <GradientStop Color="#FF1BA1E2" Offset="0"/> 
        <GradientStop Color="#FF096A99" Offset="1"/> 
       </LinearGradientBrush> 
      </Border.Background> 
     </Border> 

    </Grid> 
</UserControl> 

我用我MainPage.xaml中这个控制:

<local:TooltipControl Width="150" Height="75" x:Name="tileWidthSettings" Tooltip="Adjust the tile width of widgets" Margin="3,0,0,0" VerticalAlignment="Top"> 
    <local:TooltipControl.ToolTipControlContent> 
     <Grid Height="75" Width="150"> 

      <Grid.Effect> 
       <DropShadowEffect BlurRadius="8" Direction="0" ShadowDepth="0"/> 
      </Grid.Effect> 
      <Grid.Background> 
       <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 
        <GradientStop Color="#FF1BA1E2" Offset="0.004"/> 
        <GradientStop Color="#FF096A99" Offset="1"/> 
       </LinearGradientBrush> 
      </Grid.Background> 
      <StackPanel d:LayoutOverrides="Height" VerticalAlignment="Center" Margin="15,0"> 
       <TextBlock TextWrapping="Wrap" Text="Tile width" FontFamily="Trebuchet MS" HorizontalAlignment="Center" Foreground="White" FontSize="13.333"/> 
       <telerik:RadSlider x:Name="radSliderTileWidth" ValueChanged="radSliderTileWidth_ValueChanged" RepeatInterval="10" Value="300" Minimum="0" Margin="0" /> 
      </StackPanel> 
     </Grid> 
    </local:TooltipControl.ToolTipControlContent> 
</local:TooltipControl> 

如果我直接使用:

radSliderTileWidth.Minimum = 1.0; 

in MainPage.xaml.cs我得到NULL。即使我可以直接通过名称访问该元素,它始终为NULL。我在Loaded事件处理程序中执行它。

然后我尝试:

(tileWidthSettings.ToolTipControlContent.FindName("radSliderTileWidth") as RadSlider).Maximum = GetScreenWidth()/2; 

它仍然是NULL。

但是,如果我在某些事件处理程序中随机尝试它,它会起作用!可能是因为用户控件的模板尚未应用于加载的事件中。

然后我尝试:

RadSlider slider = tileWidthSettings.ToolTipControlContent.FindChildByType<RadSlider>(); 

这基本上是扩展方法,并使用VisualTreeHelper它的工作原理搜索儿!

那么我在这里做错了什么?我怎样才能在我的MainPage.xaml.cs中获得我的radSliderTileWidth,它以统一的方式工作,无论是在Loaded事件还是在其他事件处理程序中?

顺便说一句,我使用的是Silverlight 4.0,但我认为这是一个适用于WPF的一般概念。所以我也将它标记为WPF。

+0

顺便说一句,这是不可取的设置'UserControls'的'DataContext',如果有人使得控制的实例,并预计在DataContext被继承不会是这个案例也将被隐藏起来。例如''将失败,因为'DataContext'是'ToolipControl'本身。 – 2012-01-15 14:48:06

+0

谢谢!我同意。将在我的控制下纠正这一点。 – TCM 2012-01-16 05:03:19

+0

@ H.B:顺便说一句,如果我想在没有设置datacontext的情况下在xaml中绑定我的代码,您建议采用什么方法? – TCM 2012-01-16 05:45:53

回答

0

FrameworkElement.Loaded Silverlight中MSDN DOC,部分“加载与控制对象生存期”:

在Silverlight Loaded事件的定时从WPF的FrameworkElement.Loaded事件的定时不同。具体来说,WPF Loaded事件发生在模板应用之后。在Silverlight中,应用模板后,Loaded事件不保证发生。如果您将Loaded事件用于相对常见的控制场景,则这可能会成为问题:您想检查可视化树,以获取值作为其他值的源或更改模板化组合中的值只有在运行时才能知道新值。在这种情况下,如果直接从Loaded处理程序中调用Silverlight VisualTreeHelper方法来检查模板内容的可视化树,则可能无法正常工作。

...

相关问题