简体   繁体   中英

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. 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. But if I resize the window, it disables the round corners completely for the whole runtime.

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?

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?


 <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

  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.

So the MultiBinding "thinks" RestoreBounds was not changed and does use old values, what results to false .

To fix it just pass the window to the converter and check RestoreBounds there.

<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();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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