在ControlTemplate上覆盖IsMouseOver会使Button消失

如何解决在ControlTemplate上覆盖IsMouseOver会使Button消失

我是WPF的新手,我正在尝试为我的应用程序中的按钮定义按钮样式。我添加了以下ResourceDictionary并将其添加到App.xaml的应用程序资源中:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:local="clr-namespace:ReciepeFinder">

<Style x:Key="NavButton" TargetType="Button">

    <Setter Property="Width"
            Value="120" />
    <Setter Property="Height"
            Value="120" />
    <Setter Property="BorderThickness"
            Value="0" />

    <Setter Property="Background">
        <Setter.Value>
            <ImageBrush ImageSource="/ReciepeFinder;component/resources/images/home.png" />
        </Setter.Value>
    </Setter>

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver"
                             Value="True">
                        <Setter Property="Background">
                            <Setter.Value>
                                <ImageBrush ImageSource="/ReciepeFinder;component/resources/images/home_selected.png" />
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>

</Style>

基本上,没有悬停时,我希望按钮显示resources/images/home.png而悬停时,我希望按钮resources/images/home_selected.png。当我尝试按照上面的代码定义ControlTemplate并运行该应用程序时,该按钮没有出现。但是,如果我完全删除ControlTemplate标签,则按钮在那里带有正确的Background,但显然没有悬停效果。 我在做什么错了?

奖励问题:如果我想使用绑定功能,以便可以在其他按钮的属性中设置无悬停图像和悬停图像的路径,并使其行为相同,我怎么能做到?

解决方法

因为设置ControlTemplate时,基本上必须重新定义控件的显示方式。您仅定义了触发器,没有任何内容表示。 ContentPresenter控件将为您提供帮助。只需在ControlTemplate.Triggers和ControlTemplate之后添加一些“边框和内容”演示者。这应该可以解决问题:

</ControlTemplate.Triggers>
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
,

如果要重新设置控件的外观及其视觉状态,则必须编辑其ControlTemplate。但是,控件模板包含控件必需部分的定义,以及它在不同状态下的外观以及它们之间的过渡。要使ControlTemplate正常工作,必须实现所有这些部分和状态。您可以在e.g. for Button上找到有关MSDN上每个内置控件的必需部件和状态的信息。

您可以复制默认模板并对其进行调整,而不必从头开始创建ControlTemplate,这更加容易。您可以使用Blend或Visual Studio提取它。

您的控制模板无效,因为它实际上是空的。没有什么可以显示背景或任何内容。它不包含任何视觉效果或控件。我为您创建了一个示例控件模板,该模板应符合您的要求。

<Style x:Key="NavButton" TargetType="{x:Type Button}">
   <Setter Property="Background">
      <Setter.Value>
         <ImageBrush ImageSource="/ReciepeFinder;component/resources/images/home.png" />
      </Setter.Value>
   </Setter>
   <Setter Property="BorderThickness" Value="0"/>
   <Setter Property="HorizontalContentAlignment" Value="Center"/>
   <Setter Property="VerticalContentAlignment" Value="Center"/>
   <Setter Property="Padding" Value="1"/>
   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate TargetType="{x:Type Button}">
            <Border x:Name="border" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" SnapsToDevicePixels="true"/>
            <ControlTemplate.Triggers>
               <Trigger Property="IsMouseOver" Value="true">
                  <Setter Property="Background" TargetName="border">
                     <Setter.Value>
                        <ImageBrush ImageSource="/ReciepeFinder;component/resources/images/home_selected.png" />
                     </Setter.Value>
                  </Setter>
               </Trigger>
               <Trigger Property="IsEnabled" Value="false">
                  <Setter TargetName="border" Property="Opacity" Value="0.5"/>
               </Trigger>
            </ControlTemplate.Triggers>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>

Border显示图像背景。通常,您将ContentPresenter放在Border内,因为它会显示您分配给Content的{​​{1}}属性的内容,但是由于显示的是图像而不是内容,我已经省略了。

请注意,此模板中有Button个。这些用于绑定应用模板的控件中的指定属性。换句话说,如果直接在按钮上设置TemplateBinding或在设置位置创建Background派生的Style,则将使用此值。如果只是将值硬编码到控制模板中,则它不会更改。

关于您的奖励问题:当您使用这些NavButton时,可以如上所述直接设置TemplateBinding或在派生的Background中进行设置,因此可以重复使用。由于没有Style属性,您要么必须创建一个派生按钮,然后向其添加依赖项属性,要么创建一个附加属性,要么使用例如为此,您可以使用未使用的HoverBackground属性,尽管这感觉不合适,因为这是一种肮脏的解决方法。这是Foreground的示例,只是因为它很容易为您测试,但也适用于上述其他选项。

Foreground
<Setter Property="Foreground">
   <Setter.Value>
      <ImageBrush ImageSource="/ReciepeFinder;component/resources/images/home_selected.png" />
   </Setter.Value>
</Setter>

请注意,要在<Trigger Property="IsMouseOver" Value="true"> <Setter Property="Background" TargetName="border" Value="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Foreground}"/> </Trigger> 中访问模板化父级的属性,必须使用与Setter相同的不同绑定语法。

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

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-