0

だから私のメインアプリResourceDictionaryには、で始まるスタイルがあります

 <Style TargetType="{x:Type TabItem}" x:Key="{x:Type TabItem}">

今私がやっていることは、TabControl をオーバーライドしてカスタム コントロールを作成することです (xaml なし)。問題は、この時点でカスタム TabControl テンプレートを継承していないことです。

だから私が疑問に思っているのは、コントロールにxamlファイルがなくても特定のコントロールにバインドされていることを考慮して、テンプレートの「x:Key」にプログラムでバインドするにはどうすればよいかということです。

オンラインでこれを行うように言っている場所もあります

this.Style = (Style)FindResource("TabItem");

しかし、私の状況ではうまくいかないようです。「スタイル」は別のファイルにあり、App.Xaml リソース ディクショナリにインポートされるため、すべての TabItem を適切にオーバーライドしますが、オーバーライドしたものはオーバーライドしません。

ここに私の 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 の xaml があれば、簡単に Style="{DynamicResource {x:Type TabItem}}" (または同様のもの) に移動できますが、すべてプログラムで実行しています。

4

3 に答える 3

1

あなたはすでに試しました:

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

</Style>

ところで、x:Key を定義する必要はありません。スタイルをすべての TabControl に適用し、アプリケーション全体で機能させたい場合は、App.xaml でスタイルを設定します。


編集:あなたが何をしたいのか、まだ正確にはわかりません。(可能であれば、質問をもう一度編集してください)。

ただし、次の方法でスタイルを手動で設定することができます。

Style customStyle = (Style)Application.Current.FindResource("StyleKey");

述べたように、

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
)]
于 2012-09-22T17:53:24.873 に答える
1

派生したタブコントロールの静的コンストラクターでこれはどうですか

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

}    
于 2012-09-22T18:16:26.137 に答える
0

わかりましたので、いくつか掘り下げた後、ここで他の2つの回答の助けを借りて、これを理解することができました. FindResource の文字列を実行する代わりに、リソース ディクショナリは実際にはオブジェクト キーを持つディクショナリのように見えます。そう...

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

そして、それは私のためにそれをしました。

他の2つの回答にも感謝します。

于 2012-09-22T20:56:16.620 に答える