Silverlight: получить элемент в шаблоне данных по имени - PullRequest
2 голосов
/ 09 июня 2011

Я пытаюсь привязать HyperlinkButton внутри DataTemplate по имени после того, как пользователи установили свойство зависимости. (Весь код в Silverlight 4) К сожалению, я не знаю, к какому полю привязываться до времени выполнения. Я знаю, что я могу создать DataTemplate во время выполнения в виде строки с правильным путем привязки и внедрить его как XmlReader, но это выглядит странно. Ошибка, которую я продолжаю получать из функции FindVisualChild: «Ссылка не является допустимым визуальным DependencyObject». Как я могу получить ссылку на HyperlinkButton из таблицы данных, чтобы я мог установить привязки?

Вот мой код, с которым я работаю:

XAML:

 <sdk:DataGridTemplateColumn x:Class="CHK.WebMap.SL.Controls.DataGridURLTemplateColumn"
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" 
    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"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
    <sdk:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <HyperlinkButton x:Name="btnHyperlink" TargetName="_blank" />
        </DataTemplate>
    </sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>

CodeBehind:

public partial class DataGridURLTemplateColumn : DataGridTemplateColumn
{
    public string NavigateUri
    {
        get { return (string)GetValue(NavigateUriProperty); }
        set { SetValue(NavigateUriProperty, value); }
    }
    public static readonly DependencyProperty NavigateUriProperty =
        DependencyProperty.Register("NavigateUri", typeof(string), typeof(DataGridURLTemplateColumn), new PropertyMetadata((s, e) =>
        {
            var context = s as DataGridURLTemplateColumn;
            context.CellTemplate.LoadContent(); //create the ui elements

            var hyperlinkButton = context.FindVisualChild<HyperlinkButton>(context) as HyperlinkButton;
            hyperlinkButton.SetBinding(HyperlinkButton.NavigateUriProperty, new Binding(e.NewValue as string));
            hyperlinkButton.SetBinding(HyperlinkButton.ContentProperty, new Binding(e.NewValue as string));
        }));

    public DataGridURLTemplateColumn()
    {
        InitializeComponent();
    }


    private childItem FindVisualChild<childItem>(DependencyObject obj) where childItem : DependencyObject
    {

        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
        {

            DependencyObject child = VisualTreeHelper.GetChild(obj, i);

            if (child != null && child is childItem)
                return (childItem)child;
            else
            {
                childItem childOfChild = FindVisualChild<childItem>(child);
                if (childOfChild != null)
                    return childOfChild;
            }
        }

        return null;
    }
}

1 Ответ

5 голосов
/ 10 июня 2011

Хорошо, я понял ответ. На мой вопрос, как получить элементы внутри DataTemplate. Я действительно имел это в примере кода, но не сохранял результаты в переменную.

var hyperlinkButton = context.CellTemplate.LoadContent() as HyperlinkButton; 
...