読者です 読者をやめる 読者になる 読者になる

RunningCSharp

.net中心の開発話。記事は個人の見解であり、所属組織を代表するものてはありません。

WPF:StyleでContentプロパティを設定すると発生する問題について

C# WPF
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style TargetType="Button" x:Key="Test1">
            <Setter Property="Content">
                <Setter.Value>
                    <Border Background="Pink" >
                        <TextBlock Text="test"/>
                    </Border>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <StackPanel Orientation="Vertical">
            <Button HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource Test1}" />
            <Button HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource Test1}" />
        </StackPanel>
    </Grid>
</Window>

上記のxamlの場合、下部はStyleで設定したContentの通りピンクのボタンが表示されるが、 上側はStyleで設定したContentが表示されず、空のボタンが表示される。 対応としては、

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

上記Styleタグにx:Shared属性を追加する事で解決できます。

<Style TargetType="Button" x:Key="Test1" x:Shared="False">

x:Shared属性はデフォルトTrueなので、Styleに書かれたContentタグは一つしか生成されず、複数のオブジェクトから参照したために発生した問題と考えられそうです。

もちろん、下記のようにContentTemplateを作成する場合も問題は発生しません。

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style TargetType="Button" x:Key="Test1">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <Border Background="Pink" >
                            <TextBlock Text="test"/>
                        </Border>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <StackPanel Orientation="Vertical">
            <Button HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource Test1}" />
            <Button HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource Test1}" />
        </StackPanel>
    </Grid>
</Window>