Как я могу ссылаться на шаблон xaml из конвертера? - PullRequest
0 голосов
/ 18 января 2011

В настоящее время я застрял в проблеме с назначением различных шаблонов для управления через конвертер.

Итак, у меня есть 2 шаблона.

        <ControlTemplate x:Name="_templateA" x:Key="templateA">
            <StackPanel Grid.Column="0" Margin="0,0,5,0">
                <Blah />
            </StackPanel>
        </ControlTemplate>

        <ControlTemplate x:Name="_templateB" x:Key="templateB">
            <StackPanel Grid.Column="0" Margin="0,0,5,0">
                <Blah Blah />
            </StackPanel>
        </ControlTemplate>

и у меня есть этот элемент управления с помощью этого конвертера:

<ControlA x:Name="_controlA" >
     <Control Template="{Binding Converter={StaticResource templateConverters}}" />
</ControlA>

Мой конвертер:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        Object a;
        ControlTemplate template = null;

        try
        {
            a= value as ObjectA;
            if (value != null)
                template = a.useTemplate1 ? [templateA from xaml] : [templateB from xaml];
        }
        catch (Exception ex)
        {
            Debug.Assert(false, ex.ToString());
        }

        return toolbar;
    }

В моем конвертере, как я могу получить ссылку на мой файл xaml, чтобы он мог назначить ему мой нужный шаблон ???

Спасибо и С уважением, Кев

Ответы [ 5 ]

10 голосов
/ 18 января 2011

Возможно, вам стоит подумать о какой-то другой реализации, но вот что вы просите:

код вашего конвертера:

public class MyConverter : IValueConverter
{
    public ControlTemplate TemplateA { get; set; }
    public ControlTemplate TemplateB { get; set; }

    ... Convert methods using TemplateA and TemplateB properties...
}

использование в XAML:

<UserControl.Resources>
    <!-- templates with 'templateA' and 'templateB' keys -->
    <Converters:MyConverter x:Key="templateConverters" TemplateA="{StaticResource templateA}" TemplateB="{StaticResource templateB}" />
<UserControl.Resources>

...

<ControlA x:Name="_controlA" >
    <Control Template="{Binding Converter={StaticResource templateConverters}}" />
</ControlA>
1 голос
/ 19 января 2011

То, что вы пытаетесь выполнить, называется селектором шаблонов.Вы можете прочитать об этом, например, здесь: http://codingbandit.com/Blog/blog/wpf-data-templates-part-4-template-selectors/

Учитывая это, вы будете определять селектор шаблона (см. Свойство ContentTemplateSelector в вашем элементе управления).И его SelectTemplate метод будет выглядеть примерно так:

public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
{
    ControlTemplate template = null;
    ContentPresenter pres = container as ContentPresenter;

    try
    {
        if (value != null)
            template = item.useTemplate1 ? pres.FindResource("_templateA") : pres.FindResource("_templateB");
    }
    catch (Exception ex)
    {
        Debug.Assert(false, ex.ToString());
    }

    return toolbar;
}

Обновление: Извините, я упустил из виду, что вы пытаетесь получить ControlTemplate, а селекторы шаблонов используются для выбора DataTemplate,Но я считаю, что ваша задача также может быть достигнута с помощью шаблонов данных.

Если вы все еще хотите использовать ControlTemplate, тогда триггеры - это путь:

<ControlTemplate x:Name="_templateA" x:Key="templateA">
    <StackPanel Grid.Column="0" Margin="0,0,5,0">
        <Blah />
    </StackPanel>
</ControlTemplate>

<ControlTemplate x:Name="_templateB" x:Key="templateB">
    <StackPanel Grid.Column="0" Margin="0,0,5,0">
        <Blah Blah />
    </StackPanel>
</ControlTemplate>

<Style x:Key="MyControlStyle" TargetType="[x:Type Control}">
   <Setter Property="Template" Value="{StaticResource templateB}"/>
   <Style.Triggers>
       <DataTrigger Binding="{Binding useTemplate1}" Value="True">
           <Setter Property="Template" Value="{StaticResource templateA}"/>
       </DataTrigger>
   </Style.Triggers>
</Style>

И вы контролируете:

<ControlA x:Name="_controlA" >
     <Control Style="{StaticResource MyControlStyle}" />
</ControlA>
0 голосов
/ 18 января 2011

Я думаю, вы сможете загрузить файл ресурсов XAML из словарей ресурсов приложений, как описано здесь .

0 голосов
/ 18 января 2011

Я думаю, вы можете добиться этого лучше с помощью DataTriggers:

    <ControlTemplate>
        <StackPanel Name="TemplateA" Grid.Column="0" Margin="0,0,5,0">
            <Blah />
        </StackPanel>
        <StackPanel Name="TemplateB" Grid.Column="0" Margin="0,0,5,0">
            <Blah Blah />
        </StackPanel>

        <ControlTemplate.Triggers>
        <DataTrigger Binding="{Binding YourProp}" Value="1">
          <Setter TargetName="TemplateA" Property="Visibility" Value="Visible" />
          <Setter TargetName="TemplateB" Property="Visibility" Value="Collapsed" />
        </DataTrigger>
        <DataTrigger Binding="{Binding YourProp}" Value="0">
          <Setter TargetName="TemplateA" Property="Visibility" Value="Collapsed" />
          <Setter TargetName="TemplateB" Property="Visibility" Value="Visible" />
        </DataTrigger>
        </ControlTemplate.Triggers>

    </ControlTemplate>

Это не в моей голове, поэтому TargetName может быть SourceName и т. Д.

0 голосов
/ 18 января 2011

Поместите свои шаблоны в ресурсы некоторого контроля, дайте им x: ключи и позвоните:

ControlTemplate template = someControl.FindResource("Key") as ControlTemplate;
...