首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过触发器实现ControlTemplate中的动态ControlTemplate

通过触发器实现ControlTemplate中的动态ControlTemplate
EN

Stack Overflow用户
提问于 2016-05-16 00:12:21
回答 2查看 1K关注 0票数 1

我有一个列表框"listBox_Results“和几个ItemTemplates(其中一个是ItemTemplateStyle1),在ItemContainerStyle中,我正在为item设置模板属性。所以我想在触发器"IsSelected“中更改我的IsSelected。(常识:我希望通过动态设置不同的ItemTemplate来改变列表项的大小和内容显示)您有什么解决方案吗?

诚挚的问候

upd:如果你认为这个问题不清楚或者没有用,那么如果你先告诉我原因,然后再减去

代码:

代码语言:javascript
复制
   <ListBox Name="listBox_Results"  
             HorizontalAlignment="Stretch"
             VerticalAlignment="Stretch"
             BorderThickness="0"
             Margin="2"
             Grid.Row="0"
             ItemTemplate="{StaticResource ItemTemplateStyle1}"
             ItemsSource="{Binding}" >
            <ListBox.ItemContainerStyle>

                <Style TargetType="{x:Type ListBoxItem}">
                    <Setter Property="Background" Value="Transparent"/>
                    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                    <Setter Property="VerticalContentAlignment" Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
                    <Setter Property="Padding" Value="2,2,2,2"/>
                    <Setter Property="Margin" Value="2"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                                <Border x:Name="Bd" Margin="1" SnapsToDevicePixels="true" CornerRadius="3" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" >
                                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                </Border>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsSelected" Value="true">
                                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
                                        <Setter Property="FontWeight" Value="Bold"/>
                                        <Setter Property="Background" TargetName="Bd">
                                            <Setter.Value>
                                                #E1E1E1
                                            </Setter.Value>
                                        </Setter>
                                        ...
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-05-16 16:43:23

首先,取出您的内联样式,并创建一个ResourceDictionary来将事情保持在一起。这也将有助于我建议的模板开关。

在“资源字典”中,您将定义所需的两个模板(选定的和未选定的列表项模板)、列表项的样式和列表框本身。我正在缩写代码,只是为了说明我将如何将项目放在一起。

在ResourceDictionary中

代码语言:javascript
复制
<ControlTemplate x:Key="unselectedTemplate" TargetType="{x:Type ListBoxItem}">
   <Grid>
     <ContentPresenter />
   </Grid>
</ControlTemplate>
<ControlTemplate x:Key="selectedTemplate" TargetType="{x:Type ListBoxItem}">
   <Grid>
     <ContentPresenter Margin="3"/>
   </Grid>
</ControlTemplate>
<Style x:Key="listboxItemStyle" TargetType="{x:Type ListBoxItem}">
   <Setter Property="Template" Value="{StaticResource unselectedTemplate}"/>
   <Style.Triggers>
     <DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Self}}" Value="True">
       <Setter Property="Template" Value="{StaticResource selectedTemplate}"/>
     </DataTrigger>
    </Style.Triggers>
</Style>
<Style x:Key="listBoxStyle" TargetType="{x:Type ListBox}">
   <Setter Property="HorizontalAlignment" Value="Stretch"/>
   <Setter Property="ItemContainerStyle" Value="{StaticResource listboxItemStyle}"/>
</Style>

然后,当你在页面上创建你的列表框.只需引用列表框样式键即可。

代码语言:javascript
复制
<ListBox Name="listbox_Results" Style="{StaticResource listBoxStyle}" ItemsSource="{Binding}"/>

确保ControlTemplates是在样式之前定义的,我发现当我没有遇到错误时。此外,这样可以保持布局页面的清洁,而且如果需要再次使用,样式更容易重用。

我上传了一个非常基本的例子。

票数 2
EN

Stack Overflow用户

发布于 2016-05-16 06:06:58

您必须使用数据模板选择器,它将根据选择器中的条件选择特定的数据模板。

您必须用不同的名称在xaml中编写数据模板,并从DataTemplateSelector类文件中选择它们。为此,您需要从基类DataTemplateSelector继承

我将与您分享一些示例代码。请检查此选项,您将了解如何使用项目模板选择器。

XAML :

代码语言:javascript
复制
<Window x:Class="WpfApplication5.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication5"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <DataTemplate x:Key="NormalUserDataTemplate">
            <StackPanel>
                <TextBlock Text="{Binding Name}" />
            </StackPanel>
        </DataTemplate>
        <DataTemplate x:Key="PremiumUserDataTemplate">
            <StackPanel Background="LightBlue">
                <TextBlock Text="{Binding Name}" />
            </StackPanel>
        </DataTemplate>
        <local:PremiumUserDataTemplateSelector x:Key="myPremiumUserDataTemplateSelector" />
    </Window.Resources>
    <Grid>
        <ListView x:Name="myListView" ItemTemplateSelector="{StaticResource myPremiumUserDataTemplateSelector}">
        </ListView>
    </Grid>
</Window>

代码背后:

代码语言:javascript
复制
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        List<User> users = new List<User>();
        for (int i = 0; i < 10; ++i)
        {
            var user = new User { ID = i, Name = "Name " + i.ToString(), Age = 20 + i };
            if (i == 2 || i == 4)
            {
                user.IsPremiumUser = true;
            }
            users.Add(user);
        }
        myListView.ItemsSource = users;
    }
}

public class PremiumUserDataTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        FrameworkElement elemnt = container as FrameworkElement;
        User user = item as User;
        if(user.IsPremiumUser)
        {
            return elemnt.FindResource("PremiumUserDataTemplate") as DataTemplate;
        }
        else
        {
            return elemnt.FindResource("NormalUserDataTemplate") as DataTemplate;
        }
    }
}

public class User
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public bool IsPremiumUser { get; set; }
}
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37245029

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档