Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WPF GroupBox标题自定义_Wpf_Groupbox_Opacitymask - Fatal编程技术网

WPF GroupBox标题自定义

WPF GroupBox标题自定义,wpf,groupbox,opacitymask,Wpf,Groupbox,Opacitymask,我编辑了标准GroupBox模板,因为我想对其进行自定义。除了其他定制之外,我希望GroupBox标题在中间水平对齐,而不是在左侧或右侧对齐。标题的对齐不是问题,但是,真正的问题是为边界控件定义的OpacityMask。不透明度遮罩设置未绘制边框的groupbox标题后面的透明空间。当我将标题设置为中间位置时,我无法确定如何将透明的空格/间隙放置在groupbox标题后面 下面是我的XAML的样子:(请导航到以“Border.OpacityMask”开头的部分,该部分设置标题周围边框的透明间隙)

我编辑了标准GroupBox模板,因为我想对其进行自定义。除了其他定制之外,我希望GroupBox标题在中间水平对齐,而不是在左侧或右侧对齐。标题的对齐不是问题,但是,真正的问题是为边界控件定义的OpacityMask。不透明度遮罩设置未绘制边框的groupbox标题后面的透明空间。当我将标题设置为中间位置时,我无法确定如何将透明的空格/间隙放置在groupbox标题后面

下面是我的XAML的样子:(请导航到以“Border.OpacityMask”开头的部分,该部分设置标题周围边框的透明间隙)


非常感谢你的帮助


-Wajahat

不久前,我不得不做一些类似的事情,我想创建一个包含两个标题(一个在左侧,一个在右侧)的GroupBox。我刚刚使用Reflector获取了
BorderGapMaskConverter
的代码,并对其进行了修改以创建我自己的转换器。在这里你也可以这样做


编辑:我修改了转换器,使其适用于居中标题

这是
ControlTemplate

<ControlTemplate TargetType="{x:Type GroupBox}">
    <Grid SnapsToDevicePixels="true">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="6"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="6"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="6"/>
        </Grid.RowDefinitions>
        <Border CornerRadius="4"
            Grid.Row="1"
            Grid.RowSpan="3"
            Grid.Column="0"
            Grid.ColumnSpan="5"
            BorderThickness="{TemplateBinding BorderThickness}"
            BorderBrush="Transparent"
            Background="{TemplateBinding Background}"/>
        <Border x:Name="Header"
            Padding="3,1,3,0"
            Grid.Row="0"
            Grid.RowSpan="2"
            Grid.Column="2">
            <ContentPresenter ContentSource="Header" 
                          RecognizesAccessKey="True" 
                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
        </Border>
        <ContentPresenter Grid.Row="2"
                      Grid.Column="1"
                      Grid.ColumnSpan="3"
                      Margin="{TemplateBinding Padding}"
                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
        <Border CornerRadius="4"
            Grid.Row="1"
            Grid.RowSpan="3"
            Grid.ColumnSpan="5"
            BorderThickness="{TemplateBinding BorderThickness}"
            BorderBrush="White">
            <Border.OpacityMask>
                <MultiBinding Converter="{StaticResource CenterBorderGapMaskConverter}">
                    <Binding ElementName="Header"
                         Path="ActualWidth"/>
                    <Binding RelativeSource="{RelativeSource Self}"
                         Path="ActualWidth"/>
                    <Binding RelativeSource="{RelativeSource Self}"
                         Path="ActualHeight"/>
                </MultiBinding>
            </Border.OpacityMask>

            <Border BorderThickness="{TemplateBinding BorderThickness}"
                BorderBrush="{TemplateBinding BorderBrush}"
                CornerRadius="3">
                <Border BorderThickness="{TemplateBinding BorderThickness}"
                    BorderBrush="White"
                    CornerRadius="2"/>
            </Border>
        </Border>
    </Grid>
</ControlTemplate>

我在这里遇到了一个类似的问题(),建议的答案不是我想要的。这里建议的解决方案是简单地翻转边框,使边框中的空白空间移到右边。我希望头球在中间,而不是在右边。谢谢。非常感谢托马斯,你的建议很有魅力。然而,我对WPF感到失望,在进行这些定制时,仍然需要一个陡峭的学习曲线,这并不简单,而且仍然很麻烦。是的,WPF hard在开始时有点困难。。。但是,当您开始更好地理解它时,您可以做一些在WinForms中无法完成的事情。无论如何,通常要比在这种特定情况下更容易实现您想要的。你很少需要创建这种转换器…+1,只是在做同样的事情,当我到达
BorderGapMaskConverter
时,我想哎哟…:)干得好!您好,我想知道您是否可以发布您的双头groupbox的代码。这正是我所需要的,我找不到一个简单的方法来实现这一点。如果我能得到您的groupbox的代码,甚至是包含它的已编译DLL,我将非常感激。@Aphex,在这里:,
<ControlTemplate TargetType="{x:Type GroupBox}">
    <Grid SnapsToDevicePixels="true">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="6"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="6"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="6"/>
        </Grid.RowDefinitions>
        <Border CornerRadius="4"
            Grid.Row="1"
            Grid.RowSpan="3"
            Grid.Column="0"
            Grid.ColumnSpan="5"
            BorderThickness="{TemplateBinding BorderThickness}"
            BorderBrush="Transparent"
            Background="{TemplateBinding Background}"/>
        <Border x:Name="Header"
            Padding="3,1,3,0"
            Grid.Row="0"
            Grid.RowSpan="2"
            Grid.Column="2">
            <ContentPresenter ContentSource="Header" 
                          RecognizesAccessKey="True" 
                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
        </Border>
        <ContentPresenter Grid.Row="2"
                      Grid.Column="1"
                      Grid.ColumnSpan="3"
                      Margin="{TemplateBinding Padding}"
                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
        <Border CornerRadius="4"
            Grid.Row="1"
            Grid.RowSpan="3"
            Grid.ColumnSpan="5"
            BorderThickness="{TemplateBinding BorderThickness}"
            BorderBrush="White">
            <Border.OpacityMask>
                <MultiBinding Converter="{StaticResource CenterBorderGapMaskConverter}">
                    <Binding ElementName="Header"
                         Path="ActualWidth"/>
                    <Binding RelativeSource="{RelativeSource Self}"
                         Path="ActualWidth"/>
                    <Binding RelativeSource="{RelativeSource Self}"
                         Path="ActualHeight"/>
                </MultiBinding>
            </Border.OpacityMask>

            <Border BorderThickness="{TemplateBinding BorderThickness}"
                BorderBrush="{TemplateBinding BorderBrush}"
                CornerRadius="3">
                <Border BorderThickness="{TemplateBinding BorderThickness}"
                    BorderBrush="White"
                    CornerRadius="2"/>
            </Border>
        </Border>
    </Grid>
</ControlTemplate>
class CenterBorderGapMaskConverter : IMultiValueConverter
{
    // Methods
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        Type type = typeof(double);
        if (values == null
            || values.Length != 3
            || values[0] == null
            || values[1] == null
            || values[2] == null
            || !type.IsAssignableFrom(values[0].GetType())
            || !type.IsAssignableFrom(values[1].GetType())
            || !type.IsAssignableFrom(values[2].GetType()))
        {
            return DependencyProperty.UnsetValue;
        }

        double pixels = (double)values[0];
        double width = (double)values[1];
        double height = (double)values[2];
        if ((width == 0.0) || (height == 0.0))
        {
            return null;
        }
        Grid visual = new Grid();
        visual.Width = width;
        visual.Height = height;
        ColumnDefinition colDefinition1 = new ColumnDefinition();
        ColumnDefinition colDefinition2 = new ColumnDefinition();
        ColumnDefinition colDefinition3 = new ColumnDefinition();
        colDefinition1.Width = new GridLength(1.0, GridUnitType.Star);
        colDefinition2.Width = new GridLength(pixels);
        colDefinition3.Width = new GridLength(1.0, GridUnitType.Star);
        visual.ColumnDefinitions.Add(colDefinition1);
        visual.ColumnDefinitions.Add(colDefinition2);
        visual.ColumnDefinitions.Add(colDefinition3);
        RowDefinition rowDefinition1 = new RowDefinition();
        RowDefinition rowDefinition2 = new RowDefinition();
        rowDefinition1.Height = new GridLength(height / 2.0);
        rowDefinition2.Height = new GridLength(1.0, GridUnitType.Star);
        visual.RowDefinitions.Add(rowDefinition1);
        visual.RowDefinitions.Add(rowDefinition2);
        Rectangle rectangle1 = new Rectangle();
        Rectangle rectangle2 = new Rectangle();
        Rectangle rectangle3 = new Rectangle();
        rectangle1.Fill = Brushes.Black;
        rectangle2.Fill = Brushes.Black;
        rectangle3.Fill = Brushes.Black;
        Grid.SetRowSpan(rectangle1, 2);
        Grid.SetRow(rectangle1, 0);
        Grid.SetColumn(rectangle1, 0);
        Grid.SetRow(rectangle2, 1);
        Grid.SetColumn(rectangle2, 1);
        Grid.SetRowSpan(rectangle3, 2);
        Grid.SetRow(rectangle3, 0);
        Grid.SetColumn(rectangle3, 2);
        visual.Children.Add(rectangle1);
        visual.Children.Add(rectangle2);
        visual.Children.Add(rectangle3);
        return new VisualBrush(visual);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        return new object[] { Binding.DoNothing };
    }
}