简体   繁体   English

WPF 定制 window 圆角

[英]WPF custom window round corners

I have a problem with my xaml style for my cutom window. The style sets the edges of the window to round and looks if it is docked to an edge.我的自定义 window 的 xaml 样式有问题。该样式将 window 的边缘设置为圆形,并查看它是否停靠到边缘。 But it no longer works after changing the size of the window. On Start-up all edges are round, when I snap it to the right or the left of the screen then it shows the corners not rounded.但在更改 window 的大小后它不再起作用。在启动时所有边缘都是圆形的,当我将它捕捉到屏幕的右侧或左侧时它显示角不圆。 But if I resize the window, it disables the round corners completely for the whole runtime.但是如果我调整 window 的大小,它会在整个运行时完全禁用圆角。

How can I change my xaml code to get a behavoir that does not show rounded corners in snapped window style but if I resize my window?我如何更改我的 xaml 代码以获得在 window 样式中不显示圆角的行为,但如果我调整 window 的大小?

The folowing code is my style code.以下代码是我的样式代码。 You can set it to a window and resize the window how you like and you will see my problem with it?您可以将其设置为 window 并根据需要调整 window 的大小,您会看到我的问题吗?


 <Style x:Key="ModernWindowStyle"  TargetType="{x:Type Window}">
        <Setter Property="AllowsTransparency" Value="True"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="ResizeMode" Value="CanResize"/>
        <Setter Property="WindowStyle" Value="None"/>
        <Setter Property="MinHeight" Value="300"/>
        <Setter Property="MinWidth" Value="530"/>
        <Setter Property="MaxHeight" Value="{x:Static SystemParameters.MaximizedPrimaryScreenHeight}"/>
        <Setter Property="MaxWidth" Value="{x:Static SystemParameters.MaximizedPrimaryScreenWidth}"/>
        <Setter Property="WindowChrome.WindowChrome">
            <Setter.Value>
                <WindowChrome
                   CaptionHeight="50"
                   CornerRadius="8"
                   ResizeBorderThickness="5"/>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Window">
                    <Border BorderThickness="1"
                            BorderBrush="#FFD9D9D9">
                        <Border.Resources>
                            <core:MultiValueEqualityConverter x:Key="multiValueEqualityConverter" />
                        </Border.Resources>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition />
                            </Grid.RowDefinitions>
                           


                            <ContentPresenter Grid.Row="1" />
                        </Grid>
                        <Border.Style>
                            <Style TargetType="Border">
                                <Setter Property="CornerRadius"
                                        Value="8" />
                                <Setter Property="Background" >
                                    <Setter.Value>
                                        <LinearGradientBrush EndPoint="0,0" StartPoint="0,1">
                                            <GradientStop Color="#FF99BDCE" />
                                            <GradientStop Color="White" Offset="0.7"/>
                                        </LinearGradientBrush>
                                    </Setter.Value>
                                </Setter>
                                <Style.Triggers>

                                    <MultiDataTrigger>
                                        <MultiDataTrigger.Conditions>
                                            <Condition Value="False">
                                                <Condition.Binding>
                                                    <MultiBinding Delay="1000" Converter="{StaticResource multiValueEqualityConverter}" ConverterParameter="HI">
                                                        <Binding RelativeSource="{RelativeSource TemplatedParent}"
                                                                 Path="Width"
                                                                 Mode="OneWay" />
                                                        <Binding RelativeSource="{RelativeSource TemplatedParent}"
                                                                 Path="RestoreBounds.Width"
                                                                 Mode="OneWay" />
                                                    </MultiBinding>
                                                </Condition.Binding>
                                            </Condition>
                                            <Condition Value="False">
                                                <Condition.Binding>
                                                    <MultiBinding  Delay="1000"
                                                                   Converter="{StaticResource multiValueEqualityConverter}">
                                                        <Binding RelativeSource="{RelativeSource TemplatedParent}"
                                                                 Path="Height"
                                                                 Mode="OneWay" />
                                                        <Binding RelativeSource="{RelativeSource TemplatedParent}"
                                                                 Path="RestoreBounds.Height"
                                                                 Mode="OneWay" />
                                                    </MultiBinding>
                                                </Condition.Binding>
                                            </Condition>
                                            <Condition  Binding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=WindowState}"
                                                       Value="Normal" />
                                        </MultiDataTrigger.Conditions>
                                        <Setter Property="CornerRadius"
                                                Value="0" />
                                    </MultiDataTrigger>
                                </Style.Triggers>
                            </Style>
                        </Border.Style>
                    </Border>
                </ControlTemplate>
            </Setter.Value>

        </Setter>
    </Style>

And the MultiValueEqualityConverter和 MultiValueEqualityConverter

  public class MultiValueEqualityConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            return values?.All(o => o?.Equals(values[0]) == true) == true || values?.All(o => o == null) == true;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

I think the issue is RestoreBounds.Height or RestoreBounds.Width don't notify the value is changed, but Height or Width do.我认为问题是RestoreBounds.HeightRestoreBounds.Width不通知值已更改,但HeightWidth通知。

So the MultiBinding "thinks" RestoreBounds was not changed and does use old values, what results to false .所以MultiBinding “认为” RestoreBounds没有改变并且确实使用旧值,结果为false

To fix it just pass the window to the converter and check RestoreBounds there.要修复它,只需将 window 传递给转换器并检查那里的RestoreBounds

<Style.Triggers>
    <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
            <Condition Value="False">
                <Condition.Binding>
                    <MultiBinding  Delay="1000" Converter="{StaticResource multiValueEqualityConverter}">
                        <Binding RelativeSource="{RelativeSource TemplatedParent}"
                                Path="Height"
                                Mode="OneWay" />
                        <Binding RelativeSource="{RelativeSource TemplatedParent}" Mode="OneWay" />
                    </MultiBinding>
                </Condition.Binding>
            </Condition>
            <Condition Value="False">
                <Condition.Binding>
                    <MultiBinding Delay="1000" Converter="{StaticResource multiValueEqualityConverter}" ConverterParameter="HI">
                        <Binding RelativeSource="{RelativeSource TemplatedParent}"
                                Path="Width"
                                Mode="OneWay" />
                        <Binding RelativeSource="{RelativeSource TemplatedParent}" Mode="OneWay" />
                    </MultiBinding>
                </Condition.Binding>
            </Condition>
            <Condition  Binding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=WindowState}"
                    Value="Normal" />
        </MultiDataTrigger.Conditions>
        <Setter Property="CornerRadius"
            Value="0" />
    </MultiDataTrigger>
</Style.Triggers>

public class MultiValueEqualityConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values[1] is System.Windows.Window wnd)
        {
            return wnd.Height == wnd.RestoreBounds.Height && wnd.Width == wnd.RestoreBounds.Width;
        }
        return false;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM