none
Обратиться к элементу в ControlTemplate (WPF) RRS feed

  • Вопрос

  • Здравствуйте!

    Имеется вот такой ControlTemplate:

    <ControlTemplate x:Key="RectangleTemplate" TargetType="Thumb">
                    <UserTemplates:WordRectangle x:Name="wordRect"/>
                </ControlTemplate>

    Данный ControlTemplate используется как шаблон для Thumb.

    Thumb thumb1 = new Thumb();
                ControlTemplate template = FindResource("RectangleTemplate") as ControlTemplate;
                thumb1.Template = template;

    В элементе WordRectangle есть метод, к которому нужно обратиться из кода. Как можно вызвать этот метод, если сам объект находится в ControlTemplate объекта Thumb?

    26 февраля 2014 г. 10:14

Ответы

  • 1. Создаю пустой проект.

    2. Добавляю UserControl со следующей разметкой и кодом:

    <UserControl x:Class="WpfApplication1.UserControl1"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <Grid>
            <TextBlock x:Name="tbAlert" Text="Пока ничего не произошло" />
        </Grid>
    </UserControl>


    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }
    
        public void Alert()
        {
            tbAlert.Text = "А вот теперь произошло!";
        }
    }

    3. На главной форме разметка и код имеют вид:

    <Window xmlns:WpfApplication1="clr-namespace:WpfApplication1"  x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <ControlTemplate x:Key="RectangleTemplate" TargetType="Thumb">
                <WpfApplication1:UserControl1 x:Name="wordRect" />            
            </ControlTemplate>
        </Window.Resources>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Button Content="Click me!" Click="Button_Click" />
            <StackPanel Grid.Row="1" x:Name="spPlace" />
        </Grid>
    </Window>


    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Loaded += MainWindow_Loaded;
        }
    
        Thumb thumb1 = null;
    
        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            if (thumb1 == null)
            {
                thumb1 = new Thumb();
                ControlTemplate template = FindResource("RectangleTemplate") as ControlTemplate;
                thumb1.Template = template;
                spPlace.Children.Add(thumb1);
            }
        }
    
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            UserControl1 wr = (UserControl1)thumb1.Template.FindName("wordRect", thumb1);
            wr.Alert();
        }
    }

    4. Запускаем и кликаем:

    Как видите, все работает именно так, как должно. Проверяйте, что вы делаете неправильно. Скорее всего вы используете не тот thumb1 который на форме размещен, а свежесозданный, который или только только поместили на форму и к нему не успел примениться шаблон, либо вообще создаете новый, который на форму вообще не размещался.

    • Помечено в качестве ответа Taras KovalenkoBanned 27 февраля 2014 г. 12:14
    27 февраля 2014 г. 5:21
    Отвечающий

Все ответы

  • Добрый день.

    Как то так:

    WordRectangle wr = (WordRectangle) thumb1.Template.FindName ( "wordRect", thumb1 );
    

    26 февраля 2014 г. 10:24
    Отвечающий
  • К сожалению, такой вариант почему-то не работает.

    При попытке обращения к wr, выбрасывается исключение типа System.NullReferenceException. wr почему-то имеет значение null.

    Есть еще какие-то варианты?

    Может быть создать ControlTemplate прямо в коде, перед этим выполнив нужные действия с WordRectangle? Как это можно реализовать?


    27 февраля 2014 г. 4:56
  • 1. Создаю пустой проект.

    2. Добавляю UserControl со следующей разметкой и кодом:

    <UserControl x:Class="WpfApplication1.UserControl1"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <Grid>
            <TextBlock x:Name="tbAlert" Text="Пока ничего не произошло" />
        </Grid>
    </UserControl>


    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }
    
        public void Alert()
        {
            tbAlert.Text = "А вот теперь произошло!";
        }
    }

    3. На главной форме разметка и код имеют вид:

    <Window xmlns:WpfApplication1="clr-namespace:WpfApplication1"  x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <ControlTemplate x:Key="RectangleTemplate" TargetType="Thumb">
                <WpfApplication1:UserControl1 x:Name="wordRect" />            
            </ControlTemplate>
        </Window.Resources>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Button Content="Click me!" Click="Button_Click" />
            <StackPanel Grid.Row="1" x:Name="spPlace" />
        </Grid>
    </Window>


    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Loaded += MainWindow_Loaded;
        }
    
        Thumb thumb1 = null;
    
        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            if (thumb1 == null)
            {
                thumb1 = new Thumb();
                ControlTemplate template = FindResource("RectangleTemplate") as ControlTemplate;
                thumb1.Template = template;
                spPlace.Children.Add(thumb1);
            }
        }
    
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            UserControl1 wr = (UserControl1)thumb1.Template.FindName("wordRect", thumb1);
            wr.Alert();
        }
    }

    4. Запускаем и кликаем:

    Как видите, все работает именно так, как должно. Проверяйте, что вы делаете неправильно. Скорее всего вы используете не тот thumb1 который на форме размещен, а свежесозданный, который или только только поместили на форму и к нему не успел примениться шаблон, либо вообще создаете новый, который на форму вообще не размещался.

    • Помечено в качестве ответа Taras KovalenkoBanned 27 февраля 2014 г. 12:14
    27 февраля 2014 г. 5:21
    Отвечающий