【问题标题】:WPF Custom TabItem with Close Button带有关闭按钮的 WPF 自定义 TabItem
【发布时间】:2013-04-06 06:47:45
【问题描述】:

我正在使用 WPF 和 C#。我正在尝试创建一个包含关闭按钮的自定义 TabItem。我确实遵循了一个教程并设法让它工作 - 但是我想使用图像作为我的关闭按钮。在尝试这个时,我遇到了一些例外情况。

在 System.Deployment.dll 中发生了“System.Deployment.Application.InvalidDeploymentException”类型的第一次机会异常 mscorlib.dll 中出现了“System.IO.DirectoryNotFoundException”类型的第一次机会异常 PresentationCore.dll 中出现“System.IO.DirectoryNotFoundException”类型的第一次机会异常 mscorlib.dll 中出现了“System.IO.DirectoryNotFoundException”类型的第一次机会异常

我相信这是在抱怨找不到图像源。要设置图像源,我使用了属性窗格并在源下拉菜单中选择适当的资源。本来应该没问题的,但是一点都不好。

我想知道是否有人可以告诉我该怎么做?这很奇怪,因为如果它说找不到资源,那么资源就在那里。我使用 Resources.resx 添加了图像,并将它们添加到我的 Resources 文件夹中。都在那里...只是我的 XAML 不喜欢它。

这是我的 XAML

<UserControl x:Class="WpfApplication1.CloseableHeader"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  mc:Ignorable="d" 
  d:DesignHeight="23" d:DesignWidth="81" Margin="0">
<UserControl.Resources>
    <Style TargetType="Button" x:Key="close_hover">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Image Source="pack://siteoforigin:,,,/Resources/CloseIco.png" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style TargetType="Button" x:Key="close_normal">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Image Source="pack://siteoforigin:,,,/Resources/CloseIco_BW.png" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>
<Grid>
    <Button
        Name="button_close"
        ToolTip="Close"
        HorizontalAlignment="Right"
        VerticalAlignment="Center"
        Margin="0,0,5,0"
        Width="14"
        Height="14"
        Style="{DynamicResource close_normal}"/>
    <Label Content="TabItem"  Height="23" HorizontalAlignment="Left" 
      Margin="4,1,0,0" Name="label_TabTitle" VerticalAlignment="Top" 
      FontFamily="Courier" FontSize="12" />
</Grid>

我还应该注意,在 Visual Studio 的设计器视图中,它会按应有的方式显示选项卡(带有图像!)。

提前致谢。


更新


我现在在我的项目中走得更远,我面临的唯一问题是 Visual Studio 上的路径不存在,但是当我调试时 - 它们确实存在。资源文件夹位于 bin/Debug 内,因此图像将在调试时显示...但这意味着我将始终在设计器中出现错误。有没有办法解决这个问题,所以它适用于两者?

这是更新后的 XAML(相当大的变化)

<UserControl x:Class="WpfApplication1.CloseableHeader"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  mc:Ignorable="d" 
  d:DesignHeight="23" Margin="0">
<UserControl.Resources>
    <Style TargetType="{x:Type Button}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Border Name="border"
                            BorderThickness="0"
                    >
                        <Border.Background>
                            <ImageBrush ImageSource="pack://siteoforigin:,,,/Resources/CloseIco_BW.png" />
                        </Border.Background>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Background" TargetName="border">
                                <Setter.Value>
                                    <ImageBrush ImageSource="pack://siteoforigin:,,,/Resources/CloseIco.png" />
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>
<Grid Background="White">
    <Button
        Name="button_close"
        ToolTip="Close"
        HorizontalAlignment="Right"
        VerticalAlignment="Center"
        Margin="0,0,5,0"
        Width="14"
        Height="14"/>
    <Label Content="TabItem"  Height="23" HorizontalAlignment="Left" 
      Margin="4,1,19,0" Name="label_TabTitle" VerticalAlignment="Top" 
      FontFamily="Courier" FontSize="12" />
</Grid>

【问题讨论】:

  • 运行应用程序的时间与在设计器中看到的不同。所以你必须从你的应用程序的输出目录中看到你的想象是可以访问的。假设您的输出在某个地方是 bin/Debug。你的图片在 /Resources/CloseIco_BW.png,你可以从输出目录访问它吗?
  • 尽量不要在WPF中使用EmbeddedResource的BuildAction。据我所知,您的应用程序所需的任何资源都应标记为“编译”或“资源”,并且它与 Resources.resx 文件无关。因此,只需将新的 Resources 文件夹添加到您的项目并在那里复制所有图像。接下来在按钮模板中将 Image's Source 设置为“Resources\yourimagename.png”,然后就完成了。您可能还需要使用正确的相对路径来查找该资源文件夹,因此如果您的 UserControl 位于项目层次结构的某个深处,则 Source 可能会变为“..\..\Resources\yourimagename.png”。
  • 看起来不错,我将资源文件夹移动到 bin\Debug 并且调试似乎很好,尽管 Visual Studio 会永久抱怨无法找到图像。有没有办法解决这个问题? Resources.resx 实际上是为了什么?此外,选项卡的样式也不是应有的样式。 oi46.tinypic.com/2ewcpwx.jpg 看到这张图片。左侧是选项卡的样子(但带有关闭图像),右侧是它的实际显示方式。对此有什么想法吗?谢谢。
  • 您已将图像移至 bin/Debug 中,但可能有更好的方法。将所有这些图像添加到 VisualStudio 中的实际项目中,并将它们的 BuildAction 设置为“资源”(但不是 EmbeddedResource)。它们将被编译到您的 exe 文件中并始终存在,设计器应正确显示它们。
  • 我发现这很有用 - fabtab.codeplex.com

标签: c# wpf xaml tabitem


【解决方案1】:

有一种更简单的方法可以使用Stackpanel 组件将图像(或任何您想要的)设置为按钮。此处的按钮将具有“close.ico”作为图标和“关闭”作为水平排列的文本

    <Button Name="button_close">
     <StackPanel Orientation="Horizontal">
      <Image Source="Resources\close.ico" Width="14" Height="14" />
      <TextBlock>
       <Run Text="Close" />
      </TextBlock>
     </StackPanel>
    </Button>

回到您的问题,通过 pack-URI 设置资源地址,除非您使用嵌入式资源/内容构建操作玩一些技巧,否则您不会显示它(实际上是加载) - 但是您需要提供文件使用应用程序; 改用直接链接 (Resources\close.ico)

【讨论】:

    猜你喜欢
    • 2016-08-21
    • 2015-03-28
    • 1970-01-01
    • 2011-07-08
    • 2010-12-08
    • 1970-01-01
    • 1970-01-01
    • 2014-12-07
    • 1970-01-01
    相关资源
    最近更新 更多