Пользовательский TabItem WPF с кнопкой закрытия

Я использую WPF и С#. Я пытаюсь создать собственный TabItem, который содержит кнопку закрытия. Я следовал руководству и сумел заставить его работать, однако я хотел использовать изображения для кнопок закрытия. Попробовав это, я наткнулся на некоторые исключения.

Исключение первого шанса типа «System.Deployment.Application.InvalidDeploymentException» произошло в System.Deployment.dll Исключение первого шанса типа «System.IO.DirectoryNotFoundException» произошло в mscorlib.dll Исключение первого шанса типа «System.IO В PresentationCore.dll произошло исключение .DirectoryNotFoundException. В mscorlib.dll произошло первое случайное исключение типа «System.IO.DirectoryNotFoundException».

Я считаю, что это жалуется на то, что источник изображения не найден. Чтобы установить источник изображения, я использовал панель свойств и выбрал соответствующий ресурс в раскрывающемся меню «Источник». Это должно быть хорошо, как есть, но это совсем не хорошо.

Мне было интересно, может ли кто-нибудь дать мне несколько голов о том, что делать? Это странно, потому что если он говорит, что ресурсы не найдены, значит, ресурсы есть. Я добавил изображения с помощью Resources.resx, и он добавил их в папку «Ресурсы». Это все есть... просто моему 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>

I should also note that in the Designer View on Visual Studio, it displays the tabs as they should be (with the images!).

Заранее спасибо.


ОБНОВИТЬ


Теперь я продвинулся в своем проекте, единственная проблема, с которой я сталкиваюсь, заключается в том, что пути в 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>


person Community    schedule 13.04.2013    source источник
comment
Когда вы запускаете приложение, оно отличается от того, когда вы видите его в Дизайнере. Таким образом, вы должны увидеть, что из выходного каталога вашего приложения ваше представление доступно. Допустим, ваш вывод — это bin/Debug в каком-то месте. У вас есть изображение в /Resources/CloseIco_BW.png, можете ли вы получить к нему доступ из выходного каталога?   -  person Dzyann    schedule 14.04.2013
comment
Старайтесь не использовать BuildAction EmbeddedResource в WPF. Насколько я знаю, любые ресурсы, необходимые вашему приложению, должны быть помечены как «Компилировать» или «Ресурс», и это не имеет ничего общего с файлом Resources.resx. Так что просто добавьте новую папку Resources в свой проект и скопируйте туда все свои изображения. Затем установите источник изображения на «Resources\yourimagename.png» в шаблоне кнопки, и все готово. Вам также может потребоваться использовать правильные относительные пути, чтобы найти эту папку ресурсов, чтобы Source мог стать «..\..\Resources\yourimagename.png», если ваш UserControl находится где-то глубоко в иерархии проекта.   -  person Blablablaster    schedule 14.04.2013
comment
Кажется, хорошо, я переместил папку ресурсов в bin\Debug, и отладка выглядит нормально, хотя Visual Studio будет постоянно жаловаться на невозможность найти изображения. Есть ли способ исправить это? Для чего на самом деле Resources.resx? Кроме того, стиль вкладки не такой, каким должен быть. oi46.tinypic.com/2ewcpwx.jpg см. это изображение. Левая сторона — это то, как должна быть вкладка (но с закрытым изображением), а правая сторона — это то, как она выглядит на самом деле. Любые идеи для этого? Спасибо.   -  person    schedule 14.04.2013
comment
Вы переместили свои изображения в bin/Debug, но есть, может быть, лучший способ. Добавьте все эти изображения в свой реальный проект в VisualStudio и установите для них BuildAction как «Ресурс» (но не EmbeddedResource). Они будут скомпилированы в ваш exe файл и будут присутствовать всегда, Конструктор должен их корректно показывать.   -  person Blablablaster    schedule 14.04.2013
comment
Я нашел это полезным - fabtab.codeplex.com   -  person SyntaxGoonoo    schedule 25.11.2014


Ответы (1)


There is an easier approach to set Image (or whatever you want) to the button, with Stackpanel component. Here the button will have "close.ico" as icon and "Close" as text arranged horizontally

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

Возвращаясь к вашему вопросу, установив адрес ресурса через пакет-URI, вы не отобразите его (фактически, загрузите), если только вы не сыграете какую-нибудь хитрость со встроенными действиями по сборке ресурсов/контента, но тогда вам нужно предоставить файл с приложением ; вместо этого используйте прямую ссылку (Resources\close.ico)

person George    schedule 14.04.2013