Как установить шаблон управления в коде? - PullRequest
29 голосов
/ 22 апреля 2011

У меня есть это в XAML

<ControlTemplate TargetType="{x:Type Button}">
    <Image ...>
</ControlTemplate>

Я хочу добиться того же в коде C #. Как мне этого добиться?

ControlTemplate ct = new ControlTemplate();..
Image img = new Image();..

Теперь, как назначить это изображение для шаблона управления? Можем ли мы сделать это или я пропускаю какие-либо концепции здесь?

Ответы [ 3 ]

29 голосов
/ 22 апреля 2011

Создание шаблона в codebehind не очень хорошая идея, теоретически это можно сделать, определив ControlTemplate.VisualTree, который является FrameworkElementFactory.

ControlTemplate template = new ControlTemplate(typeof(Button));
var image = new FrameworkElementFactory(typeof(Image));
template.VisualTree = image;

Назначение свойств очень обходное, так как вам нужно использовать SetValue и SetBinding:

image.SetValue(Image.SourceProperty, ...);

Кроме того, о (ранее) принятом ответе и цитируемом материале:

Настройка шаблона ControlTemplate программно так же, как с помощью XAML, потому что мы должны использовать Класс XamlReader.

Это утверждение просто неверно, мы «не обязаны» .


Если я назначаю шаблоны во время выполнения, я определяю их как ресурс, который я могу загрузить, если мне это нужно.


Редактировать: Согласно документации FrameworkElementFactory устарело:

Этот класс является устаревшим способом программного создания шаблонов, которые являются подклассами FrameworkTemplate, такими как ControlTemplate или DataTemplate; не все функциональные возможности шаблона доступны при создании шаблона с использованием этого класса. Рекомендуемый способ программного создания шаблона - загрузить XAML из строки или потока памяти, используя метод Load класса XamlReader.

Интересно, хорошая ли эта рекомендация? Лично я бы все же пошел с определением шаблона как ресурса в XAML, если бы я мог избежать этого с помощью строк и XamlReader.

23 голосов
/ 22 апреля 2011

http://www.eggheadcafe.com/sample-code/SilverlightWPFandXAML/73fdb6a2-6044-4c43-8766-afa12618ddc1/set-controltemplate-programmatically.aspx

Настройка шаблона ControlTemplate программно так же, как с помощью XAML, потому что мы должны использовать Класс XamlReader. Например, вот код для установки шаблона кнопки, при условии, что мы хотим установить шаблон кнопки после загрузки.

private void Button_Loaded(object sender, RoutedEventArgs e) {
    var button = sender as Button;
    string template =
        "<ControlTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
            TargetType=\"Button\">" +
            "<Border>" +
                 "<ContentPresenter/>" +
            "</Border>" +
        "</ControlTemplate>";
    button.Template = (ControlTemplate)XamlReader.Parse(template);
}

Поскольку мы использовали строку для указания код XAML для шаблона, мы можем используйте метод Parse XamlReader. XamlReader также имеет метод Load, который в основном используется для потоков или Читатели XAML или XML. Обратите внимание, что мы должны включать пространство имен XML http://schemas.microsoft.com/winfx/2006/xaml/presentation потому что ControlTemplate, Border, и другие необходимые нам элементы управления определены там. Если мы не включили это, мы будем встретить исключение во время выполнения. В основном, мы должны поставить пространства имен, необходимые для шаблона.

0 голосов
/ 22 апреля 2011

Если вам нужно изменить изображение кнопки только тогда, вы можете сделать одну вещь.

  1. Создайте свойство зависимостей, которое будет представлять, когда вы хотите изменить изображение (bool) или, может быть, вы можете создать перечисление, которое имеет все возможные изображения говорят
  2. Enum Images {Image1 = 0, Image2 = 1, Image2 = 3}. Создайте свойство зависимостей «CurrentButtonImage» этого типа, которое будет связано с кнопкой.

Теперь в XAML используйте это в шаблоне кнопок

В свойстве Change объекта CurrentButtonImage обновите изображение кнопки (в коде сзади), используя

CurrentImagePropertyChangedhandler(....,...)  
{  
    switch(CurrentButtonImage)  
    {  
        case "Image1" :  
          this._ButtonImage.Fill = (DrawingBrush)csd.FindResource("Image1DrawingBrush");
          break;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...