用WPF为命名元素创建样式

6

是否可以在不编辑元素的情况下为xaml元素添加样式?

例如:

xaml元素:

<Grid>
     <Grid x:Name="A">content A</Grid>
     <Grid x:Name="B">content B</Grid>
</Grid>

和样式:

<Style x:Key="StyleForA" TargetName="A" TargetType="{x:Type Grid}" >
   <Setter Property="Background" Value="Red"/>
</Style>
<Style x:Key="StyleForB" TargetName="B" TargetType="{x:Type Grid}" >
   <Setter Property="Background" Value="Green"/>
</Style>

更新: 我有一个涉及许多样式(aero,black等)的项目。

如果我编辑元素 Style="{StaticResources StyleForA}" ,我必须编辑所有样式。 因此,我需要创建一个局部样式,影响命名元素。


1
您可以利用样式继承(参见 BasedOn)或默认样式 "传播"(TargetType 没有 x:Key 将应用于该类型所有子元素的样式)。 - Sinatr
请使用BasedOn,就像我在第一个答案中写的那样。 - Guilherme Fidelis
4个回答

2
本地情况下是无法实现的。但是,不需要修改您的XAML代码,您可以使用代码轻松实现:
    Grd1.Style = (Style) this.Resources["GridKey"];

使用 Blend behaviors 的纯 XAML 方法:

<Grid x:Name="Grd1">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <ic:ChangePropertyAction PropertyName="Style" Value="{DynamicResource GridKey}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Grid>

0

是的。我在我的App.xaml中使用这种样式,以便在所有应用程序控件周围添加一个带有错误的模板:

<Style x:Key="BordaTemplate" TargetType="Control">
        <Setter Property="Validation.ErrorTemplate">
            <Setter.Value>
                <ControlTemplate>
                    <DockPanel LastChildFill="True">                           
                        <Border BorderBrush="Red" BorderThickness="1">                           
                            <AdornedElementPlaceholder Name="myControl"/>
                        </Border>
                    </DockPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="true">
                <Setter Property="ToolTip"
                    Value="{Binding RelativeSource={x:Static RelativeSource.Self},
                    Path=(Validation.Errors).CurrentItem.ErrorContent}"/>
            </Trigger>
        </Style.Triggers>
    </Style>


 <Style TargetType="TextBox" BasedOn="{StaticResource BordaTemplate}" />        
        <Style TargetType="PasswordBox" BasedOn="{StaticResource BordaTemplate}" />
        <Style TargetType="DataGrid" BasedOn="{StaticResource BordaTemplate}" />
        <Style TargetType="ListBox"  BasedOn="{StaticResource BordaTemplate}" />
    <Style TargetType="CheckBox" BasedOn="{StaticResource BordaTemplate}" />
    <Style TargetType="ComboBox" BasedOn="{StaticResource BordaTemplate}" />
    <Style TargetType="DatePicker"  BasedOn="{StaticResource BordaTemplate}" />   

0

不像你所定义的使用target,但如果你想要将style应用于特定的control,则请使用以下方法:

 <StackPanel>
        <Button x:Name="A">
            <Button.Resources>
                <Style  TargetType="{x:Type Button}" >
                    <Setter Property="Background" Value="Red"/>
                </Style>
            </Button.Resources>
            content A</Button>
        <Button x:Name="B">
            <Button.Resources>
                <Style  TargetType="{x:Type Button}" >
                    <Setter Property="Background" Value="Green"/>
                </Style>
            </Button.Resources>
            content B</Button>
    </StackPanel>

或者创建一个基础样式,然后为您的控件创建一个BasedOn样式。

更新:如果您只想关注一次样式并确保受影响的元素:

 <Window.Resources>
    <Style  TargetType="{x:Type Button}" x:Key="First" >
        <Setter Property="Background" Value="Red"/>
    </Style>
    <Style  TargetType="{x:Type Button}" x:Key="Second" >
        <Setter Property="Background" Value="Green"/>
    </Style>
</Window.Resources>
<StackPanel>
    <Button x:Name="A">
        <Button.Resources>
            <Style  TargetType="{x:Type Button}" BasedOn="{StaticResource First}" />                  
        </Button.Resources>
        content A</Button>
    <Button x:Name="B">
        <Button.Resources>
            <Style  TargetType="{x:Type Button}"  BasedOn="{StaticResource Second}" />                    
        </Button.Resources>
        content B</Button>
</StackPanel>

我不确定你所说的“编辑元素”是什么意思?能否详细说明一下? - Kylo Ren
@Dr_klo,就您的观点,在回答中添加更新。 - Kylo Ren
正如我在答案中所说,您可以通过在App.xaml中添加样式来实现此操作。 - Guilherme Fidelis
@KyloRen,我更新了我的问题。 当任何样式中找不到关键字时,我尝试避免错误。 - Dr_klo
@Dr_klo 抱歉,没有这样的快捷方式。样式是资源,并且已经被设计为可重用组件,而不必担心实现特定类型(子类型可以使用父样式)。它必须在我们使用样式的地方处理,而不是在此之前。据我所知,这是一种单向流程。我的答案更新是否解决了问题? - Kylo Ren
显示剩余2条评论

0

我认为你可以拥有一个默认样式,并且可以在本地样式上覆盖你想要的属性。

 <Grid>
        <Grid.Resources>
            <Style TargetType="Button" x:Key="Default">
                <Setter Property="Background" Value="White"></Setter> 
                <Setter Property="Foreground" Value="Blue"/>
            </Style>

            <Style x:Key="StyleForA" BasedOn="{StaticResource Default}" TargetType="Button" >
                <Setter   Property="Background"  Value="Red" ></Setter>
            </Style>

            <Style x:Key="StyleForB" BasedOn="{StaticResource Default}" TargetType="Button" >
                <Setter   Property="Background"  Value="Green" ></Setter>
            </Style>
        </Grid.Resources>
        <StackPanel>
            <Button Style="{StaticResource StyleForA}" Width="100" x:Name="A" Click="Button_Click" Height="100">Test A</Button>
            <Button Style="{StaticResource StyleForB}" Width="100" x:Name="B" Click="Button_Click" Height="100">Test B</Button>
        </StackPanel>
    </Grid>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接