RunningCSharp

MS系開発者による、雑多な記事。記事は所属企業とは関係のない、個人の見解です。

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

<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>