微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何按名称定位具有嵌套样式的 WPF 子控件?

如何解决如何按名称定位具有嵌套样式的 WPF 子控件?

我正在尝试在 WPF 中创建自定义按钮。

我有一个 Button 的基本 XAML,按钮内有两个 TextBlock 控件。一个是由 FontAwesome 渲染的图像,一个是文本。

<TextBlock Style="{DynamicResource mediumLabel}" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="4">SETTINGS</TextBlock>
<Button  Grid.Column="1" Grid.Row="5" Grid.ColumnSpan="2" HorizontalAlignment="Stretch" Style="{DynamicResource mainButton}" Template="{DynamicResource mainButtonTemplate}">
    <Grid>
        <Grid.ColumnDeFinitions>
            <ColumnDeFinition Width="40"/>
            <ColumnDeFinition Width="200"/>
        </Grid.ColumnDeFinitions>

        <TextBlock x:Name="Image" Grid.Row="1" Grid.Column="0">cogs</TextBlock>
        <TextBlock x:Name="Label" Grid.Row="1" Grid.Column="1" Text="SETTINGS" />
    </Grid>
</Button>

我在 App.xaml 中定义了全局样式。

我可以单独定位这三个元素中的每一个,并在我的 App.xaml 中使用单独的样式。

我想做什么,我想只是为了组织和方便将来使用,我想为 Button 设置一个样式,并使用嵌套样式来定位两个 TextBlock 控件中的每一个.每个都会有不同的样式,所以我不能定位 TextBlock 类型。我想按名称引用它们。

我尝试引用主 control_name.childcontrol_name,以及仅引用控件名称

搜索时我似乎无法获得有关如何执行此操作的足够信息,因为我可能正在搜索错误的术语...

我对嵌套样式的尝试,针对嵌套样式定位进行了两次尝试。

<Style x:Key="mainButton" targettype="Button">
    <Setter Property="Background" Value="White"/>
    <Setter Property="Foreground" Value="DarkSlateGray"/>
    <Setter Property="FontSize"  Value="14"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Cursor" Value="Hand"/>
    <Style.Triggers>
        <Trigger Property="IsMouSEOver" Value="True">
            <Setter Property="Foreground" Value="DodgerBlue"/>
        </Trigger>
    </Style.Triggers>

    <Style.Resources>
        <Style targettype="{x:Reference Image}">
            <Setter Property="FontFamily" Value="/Genesis_desktop;component/tools/fontawesome-free-5.15.1-desktop/otfs/#Font Awesome 5 Free Solid"/>
            <Setter Property="FontSize"  Value="14"/>
            <Setter Property="VerticalAlignment" Value="Center"/>
            <Setter Property="HorizontalAlignment" Value="Center"/>
            <Setter Property="ForeGround" Value="orange"/>
        </Style>

        <Style targettype="{x:Reference mainButton.Label}">
            <Setter Property="FontSize"  Value="14"/>
            <Setter Property="VerticalAlignment" Value="Center"/>
            <Setter Property="HorizontalAlignment" Value="Left"/>
        </Style>
    </Style.Resources>
</Style>

解决方法

你想错了。搜索其目标的不是 61377。它是搜索其 code 的目标。
XAML 解析器创建标记对象的实例,例如"code": { "code": "61377","result": "ok" "info": "Some text" },,然后在检查本地 Style 属性后,遍历逻辑树以查找是否存在针对此实例化类型或具有匹配的键的 Style 定义的某处请求的资源键。

您想要的也非常低效,因为名称范围内的名称必须是唯一的,并且名称范围总是非常“小”。这种元素名称驱动的映射将需要仅匹配单个控件的显式样式。并且需要提前知道这个控件的名称。
这意味着您,这个单独样式的作者,可以直接访问命名控件。
因此,您可以直接在本地 <TextBlock> 中定义样式,例如FrameworkElement.Style
这具有相同的效果:Style 现在适用于您通过名称知道的单个 ResourceDictionary 元素。

如果您需要在不同的父 TextBlock.Resources 或作为合并资源声明独占样式,您通常通过应用 Style 指令命名 TextBlock,然后显式请求此资源,例如通过使用 ResourceDictionary 标记扩展。

还有 Style 返回一个名字而不是一个 x:KeyStaticResource 属性的类型为 x:Reference。此属性使用 Type,它允许分配一个字符串值,然后将其转换为 TargetType

您想要的默认情况下是不可能的。样式是纯类型特定的(当定义为隐式资源时)或由它们的 Type 值显式映射(作为附加约束)。另一方面,您想要的已经以不同的形式存在,可以通过使用本地资源或 TypeConverter 指令以及 Typex:Key 标记扩展来实现。>

,

您的样式的问题在于 嵌套 样式是在其 Resources 中定义的。这些只能在此样式的范围内访问。因此,按钮不能,因为它具有不同的作用域。

我不认为以这种方式嵌套样式是可能的,但您也可以为按钮的 DataTemplate 创建一个 Content 并将样式嵌套在那里。为它们分配一个键并从您的 TextBlock 中引用它们。在您的 mainButton 样式中,您可以添加一个 setter 来将 ContentTemplate 设置为此模板。您还可以在按钮上显式设置 ContentTemplate(但这意味着您必须将数据模板移出样式)。我希望这是您想要实现的嵌套或封装。

<Style x:Key="mainButton" TargetType="Button">
   <Style.Resources>
      <DataTemplate x:Key="MyButtoDataTemplate">
         <DataTemplate.Resources>
            <Style x:Key="ImageStyle" TargetType="{x:Type TextBlock}">
               <Setter Property="FontFamily" Value="/Genesis_desktop;component/tools/fontawesome-free-5.15.1-desktop/otfs/#Font Awesome 5 Free Solid"/>
               <Setter Property="FontSize"  Value="14"/>
               <Setter Property="VerticalAlignment" Value="Center"/>
               <Setter Property="HorizontalAlignment" Value="Center"/>
               <Setter Property="Foreground" Value="orange"/>
            </Style>
            <Style x:Key="LabelStyle" TargetType="{x:Type TextBlock}">
               <Setter Property="FontSize"  Value="14"/>
               <Setter Property="VerticalAlignment" Value="Center"/>
               <Setter Property="HorizontalAlignment" Value="Left"/>
            </Style>
         </DataTemplate.Resources>
         <Grid>
            <Grid.ColumnDefinitions>
               <ColumnDefinition Width="40"/>
               <ColumnDefinition Width="200"/>
            </Grid.ColumnDefinitions>

            <TextBlock x:Name="Image" Grid.Column="0" Style="{StaticResource ImageStyle}">cogs</TextBlock>
            <TextBlock x:Name="Label" Grid.Column="1" Style="{StaticResource LabelStyle}" Text="SETTINGS" />
         </Grid>
      </DataTemplate>
   </Style.Resources>
   <Setter Property="Background" Value="White"/>
   <Setter Property="Foreground" Value="DarkSlateGray"/>
   <Setter Property="FontSize"  Value="14"/>
   <Setter Property="BorderThickness" Value="0"/>
   <Setter Property="Cursor" Value="Hand"/>
   <Setter Property="ContentTemplate" Value="{StaticResource MyButtoDataTemplate}"/>
   <Style.Triggers>
      <Trigger Property="IsMouseOver" Value="True">
         <Setter Property="Foreground" Value="DodgerBlue"/>
      </Trigger>
   </Style.Triggers>
</Style>

您的 Button 定义简化为这样,因为样式已经定义了一切:

<Button  Grid.Column="1"
         Grid.Row="5"
         Grid.ColumnSpan="2"
         HorizontalAlignment="Stretch"
         Style="{DynamicResource mainButton}"
         Template="{DynamicResource mainButtonTemplate}"/>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?