0

私は WPF を初めて使用しますが、フォーム MDI から移行することで製品がどのように改善されるかを説明するために、デモ アプリをまとめようとしています。

より良い名前がないため、ここで「TabbedPanel」と呼んだ TabControl のテンプレートがあります。この TabbedPanel には、「フルスクリーン」と「閉じる」という 2 つの追加ボタンがあります。以下のコードでは、これらのボタンの可視性をプロパティにバインドするために 2 つの異なる方法を試みましたが、どちらも期待どおりに機能していないことがわかります。

<UserControl x:Class="myApp.TabbedPanel"
         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="300" d:DesignWidth="300">
<UserControl.Resources>
    <ControlTemplate x:Key="TabControlControlTemplate1" TargetType="{x:Type TabControl}">
        <Grid ClipToBounds="True" SnapsToDevicePixels="True" KeyboardNavigation.TabNavigation="Local">
            <Grid.Background>
                <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
                    <LinearGradientBrush.RelativeTransform>
                        <TransformGroup>
                            <ScaleTransform CenterY="0.5" CenterX="0.5"/>
                            <SkewTransform CenterY="0.5" CenterX="0.5"/>
                            <RotateTransform Angle="90" CenterY="0.5" CenterX="0.5"/>
                            <TranslateTransform/>
                        </TransformGroup>
                    </LinearGradientBrush.RelativeTransform>
                    <GradientStop Color="#FFD5D5D6" Offset="0.5"/>
                    <GradientStop Color="#FF646464" Offset="1"/>
                    <GradientStop Color="#FF606060"/>
                </LinearGradientBrush>
            </Grid.Background>
            <Grid.ColumnDefinitions>
                <ColumnDefinition x:Name="ColumnDefinition0"/>
                <ColumnDefinition x:Name="ColumnDefinition1" Width="0"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition x:Name="RowDefinition0" Height="Auto"/>
                <RowDefinition x:Name="RowDefinition1" Height="*"/>
            </Grid.RowDefinitions>
            <TabPanel x:Name="HeaderPanel" Grid.Column="0" IsItemsHost="True" Margin="2,2,2,0" Grid.Row="0" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1"/>
            <Border x:Name="ContentPanel" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="0" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
                <ContentPresenter x:Name="PART_SelectedContentHost" ContentTemplate="{TemplateBinding SelectedContentTemplate}" Content="{TemplateBinding SelectedContent}" ContentStringFormat="{TemplateBinding SelectedContentStringFormat}" ContentSource="SelectedContent" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
            </Border>
            <Button Name="btnFullscreen" Content="FULLSCREEN" HorizontalAlignment="Right" Height="23" Margin="0,0,25.863,0" VerticalAlignment="Top" Width="Auto" FontWeight="Bold" Click="btnFullscreen_Click" Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=FullscreenButtonVisibility}">
                <Button.Background>
                    <LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
                        <GradientStop Color="#FF99945E" Offset="0"/>
                        <GradientStop Color="#FFEBEBEB" Offset="0.569"/>
                        <GradientStop Color="#FFDDDDDD" Offset="0.259"/>
                        <GradientStop Color="#FFB4B04D" Offset="1"/>
                    </LinearGradientBrush>
                </Button.Background>
            </Button>
            <Button Name="btnClose" Content="X" HorizontalAlignment="Right" Height="23" Margin="0" VerticalAlignment="Top" Width="25.863" BorderBrush="#FF2C0101" Foreground="White" FontWeight="Bold" Click="btnClose_Click" Visibility="{Binding Mode=TwoWay, Path=CloseButtonVisibility}">
                <Button.Background>
                    <LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
                        <GradientStop Color="#FF850303" Offset="0"/>
                        <GradientStop Color="#FFF00000" Offset="0.5"/>
                        <GradientStop Color="#FF720707" Offset="0.004"/>
                        <GradientStop Color="#FF970000" Offset="1"/>
                    </LinearGradientBrush>
                </Button.Background>
            </Button>
        </Grid>
        <ControlTemplate.Triggers>
            <Trigger Property="TabStripPlacement" Value="Bottom">
                <Setter Property="Grid.Row" TargetName="HeaderPanel" Value="1"/>
                <Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
                <Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
                <Setter Property="Height" TargetName="RowDefinition1" Value="Auto"/>
                <Setter Property="Margin" TargetName="HeaderPanel" Value="2,0,2,2"/>
            </Trigger>
            <Trigger Property="TabStripPlacement" Value="Left">
                <Setter Property="Grid.Row" TargetName="HeaderPanel" Value="0"/>
                <Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
                <Setter Property="Grid.Column" TargetName="HeaderPanel" Value="0"/>
                <Setter Property="Grid.Column" TargetName="ContentPanel" Value="1"/>
                <Setter Property="Width" TargetName="ColumnDefinition0" Value="Auto"/>
                <Setter Property="Width" TargetName="ColumnDefinition1" Value="*"/>
                <Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
                <Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
                <Setter Property="Margin" TargetName="HeaderPanel" Value="2,2,0,2"/>
            </Trigger>
            <Trigger Property="TabStripPlacement" Value="Right">
                <Setter Property="Grid.Row" TargetName="HeaderPanel" Value="0"/>
                <Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
                <Setter Property="Grid.Column" TargetName="HeaderPanel" Value="1"/>
                <Setter Property="Grid.Column" TargetName="ContentPanel" Value="0"/>
                <Setter Property="Width" TargetName="ColumnDefinition0" Value="*"/>
                <Setter Property="Width" TargetName="ColumnDefinition1" Value="Auto"/>
                <Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
                <Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
                <Setter Property="Margin" TargetName="HeaderPanel" Value="0,2,2,2"/>
            </Trigger>
            <Trigger Property="IsEnabled" Value="False">
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
</UserControl.Resources>
    <TabControl Name="tabitems" Background="white" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Template="{DynamicResource TabControlControlTemplate1}">
        <TabControl.Resources>
            <Style TargetType="TabItem">
                <Setter Property="AllowDrop" Value="True"/>
                <EventSetter Event="PreviewMouseMove" Handler="TabItem_PreviewMouseMove"/>
                <EventSetter Event="Drop" Handler="TabItem_Drop"/>
            </Style>
            <Style TargetType="TabControl">
                <Setter Property="AllowDrop" Value="True"/>
                <EventSetter Event="PreviewMouseMove" Handler="TabItem_PreviewMouseMove"/>
                <EventSetter Event="Drop" Handler="TabItem_Drop"/>
            </Style>
        </TabControl.Resources>
    </TabControl>

以下は、C# コードの関連部分を示しています。INotifyPropertyChanged から継承し、CloseButtonVisibility と FullscreenButtonVisibility の 2 つのプロパティのインターフェイスを実装します。

public partial class TabbedPanel : UserControl, INotifyPropertyChanged
    {
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
    protected bool SetField<T>(ref T field, T value, string propertyName)
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }

    public TabbedPanel()
    {
        InitializeComponent();
    }

    public event RoutedEventHandler Close;
    public event RoutedEventHandler Fullscreen;

    private Visibility closeButtonVisibility;
    public Visibility CloseButtonVisibility
    {
        get { return closeButtonVisibility; }
        set 
        {
            SetField(ref closeButtonVisibility, value, "CloseButtonVisibility");
        }
    }

    private Visibility fullscreenButtonVisibility;
    public Visibility FullscreenButtonVisibility
    {
        get { return fullscreenButtonVisibility; }
        set
        {
            SetField(ref fullscreenButtonVisibility, value, "FullscreenButtonVisibility");
        }
    }

    public ItemCollection Tabs
    {
        get { return tabitems.Items; }
    }

次に、MainWindow.xaml の次のコードで TabbedPanel を使用します。次に、FullscreenButtonVisibility と CloseButtonVisibility が Visibility.Hidden に初期化されます。

<Grid x:Name="LayoutRoot" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition Height="1*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*" />
        </Grid.ColumnDefinitions>
        <local:TabbedPanel Grid.Row="0" FullscreenButtonVisibility="Hidden" CloseButtonVisibility="Hidden">
            <local:TabbedPanel.Tabs>
                <TabItem Header="Top">
                    <Image HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Source="Artwork\ImageTop.JPG"/>
                </TabItem>
                <TabItem Header="Left">
                    <Image HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Source="Artwork\ImageBottom.BMP"/>
                </TabItem>
                <TabItem Header="Bottom">
                    <Image HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Source="Artwork\ImageLeft.JPG"/>
                </TabItem>
                <TabItem Header="Right">
                    <Image HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Source="Artwork\ImageRight.JPG"/>
                </TabItem>
            </local:TabbedPanel.Tabs>
        </local:TabbedPanel>
    </Grid>

これを使用すると、「フルスクリーン」ボタンと「閉じる」ボタンが非表示になると思っていましたが、表示されています。C# でプロシージャルに可視性を設定できると確信していますが、XAML を介して行う方がクリーンです。また、私はここでいくつかのルート WPF の概念が欠けていると確信していますが、私は数日間だけ自分自身を教えてきました...助けていただければ幸いです。

4

0 に答える 0