UIElement null при использовании пользовательского DependencyProperty - PullRequest
0 голосов
/ 15 января 2012

Я создал простой пользовательский контроль для всплывающей подсказки:

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;

в MainPage.xaml.cs, я получаю NULL.Хотя я могу получить доступ к элементу напрямую через имя, оно всегда равно NULL.Я делаю это в обработчике событий Loaded.

Затем я попытался:

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

Это было все еще NULL.

Но, если я попробую это случайно в каком-то обработчике событий, этоработает!Вероятно, это потому, что шаблон usercontrol не был применен в загруженном событии.

Затем я попытался:

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

, который в основном является методом расширения, и ищет дочернего элемента с помощью VisualTreeHelper, он работает!

Так что я тут не так делаю?Как я могу получить свой radSliderTileWidth в моем MainPage.xaml.cs, который работает унифицированно, будь то событие Loaded или другие обработчики событий?

Кстати, я использую Silverlight 4.0, но я думаю, что это общая концепциячто относится и к WPF.Так что я тоже отмечаю его как WPF.

1 Ответ

0 голосов
/ 15 января 2012

См. Документ MSDN FrameworkElement.Loaded в Silverlight, раздел «Время жизни загруженного и управляющего объекта»:

Время события Loaded в Silverlight отличается от временисобытия FrameworkElement.Loaded в WPF.В частности, событие WPF Loaded наступает после применения шаблона.В Silverlight событие Loaded не гарантируется после применения шаблона.Это может быть проблемой для вас, если вы используете событие Loaded для относительно распространенного сценария управления: вы хотите изучить визуальное дерево, либо получить значение в качестве источника чего-то другого, либо изменить значение в шаблонной композиции, гдеВы можете узнать новое значение только во время выполнения.В этом случае вызовы методов Silverlight VisualTreeHelper для проверки визуального дерева содержимого шаблона могут не работать, если вы делаете их непосредственно из обработчика Loaded.

...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...