Wpf 使用绑定到控件的键替代控件样式

Wpf 使用绑定到控件的键替代控件样式,wpf,styles,wpf-controls,Wpf,Styles,Wpf Controls,因此,在我的主应用程序ResourceDictionary中,我有一个以 <Style TargetType="{x:Type TabItem}" x:Key="{x:Type TabItem}"> 但这在我的情况下似乎不起作用。“样式”在一个单独的文件中,并导入到我的App.Xaml资源字典中……因此它会正确地覆盖所有TabItems,但不会覆盖我覆盖的TabItems 这是我的App.xaml <Application x:Class="Octgn.OctgnApp"

因此,在我的主应用程序ResourceDictionary中,我有一个以

 <Style TargetType="{x:Type TabItem}" x:Key="{x:Type TabItem}">
但这在我的情况下似乎不起作用。“样式”在一个单独的文件中,并导入到我的App.Xaml资源字典中……因此它会正确地覆盖所有TabItems,但不会覆盖我覆盖的TabItems

这是我的App.xaml

<Application x:Class="Octgn.OctgnApp" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <Application.Resources>
    <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>

        <ResourceDictionary Source="/Resources/Themes/Full/ExpressionDark.xaml"/>
       </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
  </Application.Resources>
</Application>

以及ExpressionDark.xaml中的项(由于较大,所以略为截断)

<Style d:IsControlPart="True" TargetType="{x:Type TabItem}" x:Key="{x:Type TabItem}">
    <Setter Property="Foreground" Value="{DynamicResource TextBrush}" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabItem}">
                <Grid x:Name="grid" Margin="2,1,2,3">
                    <Grid.LayoutTransform>
                        <TransformGroup>
                            <ScaleTransform ScaleX="1" ScaleY="1"/>
                            <SkewTransform AngleX="0" AngleY="0"/>
                            <RotateTransform Angle="0"/>
                            <TranslateTransform X="0" Y="0"/>
                        </TransformGroup>
                    </Grid.LayoutTransform>
                    <Border x:Name="border" BorderBrush="{x:Null}" CornerRadius="2,2,2,2" Opacity="0.5">
                        <Border.Background>
                            <LinearGradientBrush EndPoint="0.5,0.976" StartPoint="0.5,0.039">
                                <GradientStop Color="#7F595959" Offset="0" />
                                <GradientStop Color="#19FFFFFF" Offset="1" />
                            </LinearGradientBrush>
                        </Border.Background>
                    </Border>
                    <Border x:Name="SelectedBorder" BorderBrush="{x:Null}" CornerRadius="2,2,2,2" Opacity="0" Background="{DynamicResource SelectedBackgroundBrush}"/>
                    <Border x:Name="HoverBorder" BorderBrush="{x:Null}" CornerRadius="2,2,2,2" Opacity="0">
                        <Border.Background>
                            <LinearGradientBrush EndPoint="0.5,0.976" StartPoint="0.5,0.039">
                                <GradientStop Color="#7F595959" Offset="0" />
                                <GradientStop Color="#19FFFFFF" Offset="1" />
                            </LinearGradientBrush>
                        </Border.Background>
                    </Border>
                    <Grid>
                        <ContentPresenter x:Name="ContentSite" RecognizesAccessKey="True" ContentSource="Header" d:LayoutOverrides="Width, Height" HorizontalAlignment="Center" Margin="6,1,6,1" VerticalAlignment="Center" />
                    </Grid>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

此样式自动应用于TabItem,但我尝试将其应用于我的TabItem覆盖

这是代码

/// <summary>
/// The chat bar item.
/// </summary>
public class ChatBarItem : TabItem
{
    /// <summary>
    /// Sets the Chat Room
    /// </summary>
    private readonly NewChatRoom room;

    /// <summary>
    /// Initializes static members of the <see cref="ChatBarItem"/> class.
    /// </summary>
    static ChatBarItem()
    {
        DefaultStyleKeyProperty.OverrideMetadata(
            typeof(ChatBarItem), new FrameworkPropertyMetadata(typeof(TabItem)));
    }   

    /// <summary>
    /// Initializes a new instance of the <see cref="ChatBarItem"/> class.
    /// </summary>
    /// <param name="chatRoom">
    /// The chat Room.
    /// </param>
    public ChatBarItem(NewChatRoom chatRoom)
    {
        this.room = chatRoom;
        this.ConstructControl();
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="ChatBarItem"/> class.
    /// </summary>
    public ChatBarItem()
    {
        this.room = null;
        this.ConstructControl();
    }

    /// <summary>
    /// Constructs this control
    /// </summary>
    private void ConstructControl()
    {
        //this.Background = Brushes.Transparent;
        //this.BorderThickness = new Thickness(0);
        //this.Style = (Style)FindResource("TabItem");
        // this is where I want to set the style of this control

        // Main content object
        var mainBorder = new Border { Margin = new Thickness(5) };

        // Main content grid
        var g = new Grid();
        g.ColumnDefinitions.Add(new ColumnDefinition());
        g.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(16) });

        // Create item label
        var label = new TextBlock() { VerticalAlignment = VerticalAlignment.Center };
        if (this.IsInDesignMode() || this.room == null)
        {
            label.Inlines.Add(new Run("test"));
        }
        else
        {
            label.Inlines.Add(new Run(this.room.GroupUser.User.User));
        }

        // Create close button
        var borderClose = new Border { Width = 16, Height = 16 };
        var imageClose = new Image()
            {
                Source = new BitmapImage(new Uri("pack://application:,,,/Octgn;component/Resources/close.png")), 
                Stretch = Stretch.Uniform
            };

        // --Add items to items

        // Add close image to closeBorder
        borderClose.Child = imageClose;

        // Add Close 'button' to grid
        g.Children.Add(borderClose);
        Grid.SetColumn(borderClose, 1);

        // Add label to main grid
        g.Children.Add(label);

        // Add main grid to main border
        mainBorder.Child = g;

        // Add main grid to this
        this.Header = mainBorder;
    }
}
//
///聊天栏项目。
/// 
公共类聊天室项目:TabItem
{
/// 
///设置聊天室
/// 
私人只读聊天室;
/// 
///初始化类的静态成员。
/// 
静态ChatBarItem()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(ChatBarItem),新的框架属性ymetadata(typeof(TabItem));
}   
/// 
///初始化类的新实例。
/// 
/// 
///聊天室。
/// 
公共聊天室(新聊天室聊天室)
{
this.room=聊天室;
this.ConstructControl();
}
/// 
///初始化类的新实例。
/// 
公共聊天室()
{
this.room=null;
this.ConstructControl();
}
/// 
///构造此控件
/// 
私有控件()
{
//this.Background=画笔.Transparent;
//此边界厚度=新厚度(0);
//this.Style=(Style)FindResource(“TabItem”);
//这就是我要设置此控件样式的地方
//主要内容对象
var mainBorder=新边框{边距=新厚度(5)};
//主内容网格
var g=新网格();
g、 添加(新ColumnDefinition());
g、 Add(新的ColumnDefinition{Width=newGridLength(16)});
//创建项目标签
var label=new TextBlock(){VerticalAlignment=VerticalAlignment.Center};
if(this.IsInDesignMode()| | this.room==null)
{
label.Inlines.Add(新运行(“测试”);
}
其他的
{
label.Inlines.Add(新运行(this.room.GroupUser.User.User));
}
//创建关闭按钮
var borderClose=新边框{Width=16,Height=16};
var imageClose=新图像()
{
Source=新的位图图像(新的Uri(“pack://application:,,,/Octgn;组件/Resources/close.png”),
拉伸=拉伸.均匀
};
//--将项目添加到项目中
//将关闭图像添加到关闭边框
borderClose.Child=imageClose;
//将关闭“按钮”添加到网格
g、 添加(borderClose);
Grid.SetColumn(borderClose,1);
//将标签添加到主栅格
g、 添加(标签);
//将主栅格添加到主边框
mainBorder.Child=g;
//将主栅格添加到此
this.Header=mainBorder;
}
}
如果我有一个用于TabItem的xaml,我可以轻松地使用Style=“{DynamicResource{x:typetabitem}}”(或类似的东西),但我是通过编程来完成的。

您已经尝试过:

<Style TargetType="{x:Type TabControl}" BasedOn="{StaticResource {x:Type TabControl}}">

</Style>
如前所述

static MyCustomTabControl()
{
     DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomTabControl), new FrameworkPropertyMetadata(typeof(TabControl)));
} 
但这只有在以下条件下才能起作用:

1) 控件的样式位于以下文件中:Themes\Generic.xaml

2) 文件“Generic.xaml”具有值为Page的属性“BuildAction”

3) AssemblyInfo.cs包含:

[assembly: ThemeInfo (
     ResourceDictionaryLocation.None,
     ResourceDictionaryLocation.SourceAssembly
)]

在dervied选项卡控件的静态构造函数中,这是什么

static MyCustomTabControl()
{
     DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomTabControl), new FrameworkPropertyMetadata(typeof(TabControl)));

}    

好吧,在仔细研究之后,在其他两个答案的帮助下,我终于找到了答案。与为FindResource执行字符串不同的是,资源字典实际上是一个具有对象键的dictionary。所以

this.Style = (Style)Application.Current.FindResource(typeof(TabItem));
我就是这么做的


再次感谢其他两个答案。

在这一个答案中,我得到了一个关于“检测到循环”或其他一些错误…我需要的是一种方法,不使用xaml,将其样式设置为样式的x:键。请查看我的修订问题。a是的,感谢更新问题,我也会编辑我的答案。好的,用一些我认为相关的代码再次编辑。我现在没有时间,但是文件generic.xaml,你可以尝试这样设置:是的,我仍然没有得到正确的样式,结果与另一个答案相同。
static MyCustomTabControl()
{
     DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomTabControl), new FrameworkPropertyMetadata(typeof(TabControl)));

}    
this.Style = (Style)Application.Current.FindResource(typeof(TabItem));