MaterialDesignInXamlToolkit icon indicating copy to clipboard operation
MaterialDesignInXamlToolkit copied to clipboard

The UniformCornerRadius of Card Control is not working

Open SandyHoDsal opened this issue 1 year ago • 6 comments

Bug explanation

Before upgrade to 5.1.0, the corner radius in card control looks normalL: original

But after upgrade to 5.1.0, you can see the corner radius is not working, there is a panel or grid on top of it: broken

I am setting MaterialDesign3.Defaults.xaml and MaterialDesign2.Defaults.xaml in my app.xml, both have the same problem

Version

5.1.0

SandyHoDsal avatar Aug 20 '24 02:08 SandyHoDsal

OK, I have figure out the problem. It's because double border is added.

The corrected Card.xaml should be like this:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:converters="clr-namespace:MaterialDesignThemes.Wpf.Converters"
                    xmlns:wpf="clr-namespace:MaterialDesignThemes.Wpf">

  <ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Shadows.xaml" />
  </ResourceDictionary.MergedDictionaries>

  <Style x:Key="MaterialDesignElevatedCard" TargetType="{x:Type wpf:Card}">
    <Setter Property="Background" Value="{DynamicResource MaterialDesign.Brush.Card.Background}" />
    <Setter Property="BorderThickness" Value="0" />
    <Setter Property="BorderBrush" Value="{DynamicResource MaterialDesign.Brush.Card.Border}" />
    <Setter Property="Focusable" Value="False" />
    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="{x:Type wpf:Card}">
          <ControlTemplate.Resources>
            <converters:ShadowOpacityMaskConverter x:Key="ShadowOpacityMaskConverter" />
          </ControlTemplate.Resources>
          <Grid Background="Transparent">
            <AdornerDecorator CacheMode="{Binding RelativeSource={RelativeSource Self}, Path=(wpf:ShadowAssist.CacheMode)}">
              <AdornerDecorator.OpacityMask>
                <MultiBinding Converter="{StaticResource ShadowOpacityMaskConverter}">
                  <Binding Path="ActualWidth" RelativeSource="{RelativeSource TemplatedParent}" />
                  <Binding Path="ActualHeight" RelativeSource="{RelativeSource TemplatedParent}" />
                  <Binding Path="(wpf:ElevationAssist.Elevation)" RelativeSource="{RelativeSource TemplatedParent}" />
                </MultiBinding>
              </AdornerDecorator.OpacityMask>
              <Border CornerRadius="{TemplateBinding UniformCornerRadius, Converter={x:Static converters:DoubleToCornerRadiusConverter.Instance}}"
                      BorderBrush="{TemplateBinding BorderBrush}"
                      BorderThickness="{TemplateBinding BorderThickness}"
                      Effect="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(wpf:ElevationAssist.Elevation), Converter={x:Static converters:ShadowConverter.Instance}}">
                <Border x:Name="PART_ClipBorder"
                        Padding="{TemplateBinding Padding}"
                        Background="{TemplateBinding Background}"
                        Clip="{TemplateBinding ContentClip}">
                  <ContentPresenter x:Name="ContentPresenter"
                                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                    Content="{TemplateBinding ContentControl.Content}"
                                    ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
                                    ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
                                    ContentTemplateSelector="{TemplateBinding ContentControl.ContentTemplateSelector}" />
                </Border>
              </Border>
            </AdornerDecorator>
          </Grid>
          <ControlTemplate.Triggers>
            <Trigger Property="ClipContent" Value="True">
              <Setter TargetName="ContentPresenter" Property="Clip" Value="{Binding ContentClip, RelativeSource={RelativeSource TemplatedParent}}" />
            </Trigger>
          </ControlTemplate.Triggers>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
    <Setter Property="VerticalContentAlignment" Value="Stretch" />
    <Setter Property="wpf:ElevationAssist.Elevation" Value="Dp1" />
  </Style>

  <Style x:Key="MaterialDesignOutlinedCard" TargetType="{x:Type wpf:Card}">
    <Setter Property="Background" Value="{DynamicResource MaterialDesign.Brush.Card.Background}" />
    <Setter Property="BorderThickness" Value="1" />
    <Setter Property="BorderBrush" Value="{DynamicResource MaterialDesign.Brush.Card.Border}" />
    <Setter Property="Focusable" Value="False" />
    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="{x:Type wpf:Card}">
          <Border BorderBrush="{TemplateBinding BorderBrush}"
                  BorderThickness="{TemplateBinding BorderThickness}"
                  CornerRadius="{TemplateBinding UniformCornerRadius, Converter={x:Static converters:DoubleToCornerRadiusConverter.Instance}}">
            <Border x:Name="PART_ClipBorder"
                    Padding="{TemplateBinding Padding}"
                    Background="{TemplateBinding Background}"
                    Clip="{TemplateBinding ContentClip}">
              <ContentPresenter x:Name="ContentPresenter"
                                Margin="{TemplateBinding Padding}"
                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                Content="{TemplateBinding ContentControl.Content}"
                                ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
                                ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
                                ContentTemplateSelector="{TemplateBinding ContentControl.ContentTemplateSelector}" />
            </Border>
          </Border>
          <ControlTemplate.Triggers>
            <Trigger Property="ClipContent" Value="True">
              <Setter TargetName="ContentPresenter" Property="Clip" Value="{Binding ContentClip, RelativeSource={RelativeSource TemplatedParent}}" />
            </Trigger>
          </ControlTemplate.Triggers>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
    <Setter Property="VerticalContentAlignment" Value="Stretch" />
  </Style>

</ResourceDictionary>

SandyHoDsal avatar Aug 20 '24 03:08 SandyHoDsal

The problem is here, the Border is added twice and x:name=PART_ClipBorder only apply to one of it:

  <Grid Background="Transparent">
            <AdornerDecorator CacheMode="{Binding RelativeSource={RelativeSource Self}, Path=(wpf:ShadowAssist.CacheMode)}">
              <AdornerDecorator.OpacityMask>
                <MultiBinding Converter="{StaticResource ShadowOpacityMaskConverter}">
                  <Binding Path="ActualWidth" RelativeSource="{RelativeSource TemplatedParent}" />
                  <Binding Path="ActualHeight" RelativeSource="{RelativeSource TemplatedParent}" />
                  <Binding Path="(wpf:ElevationAssist.Elevation)" RelativeSource="{RelativeSource TemplatedParent}" />
                </MultiBinding>
              </AdornerDecorator.OpacityMask>
              <Border
                CornerRadius="{TemplateBinding UniformCornerRadius, Converter={x:Static converters:DoubleToCornerRadiusConverter.Instance}}"
                Effect="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(wpf:ElevationAssist.Elevation), Converter={x:Static converters:ShadowConverter.Instance}}"
                >
                <Border Padding="{TemplateBinding Padding}"
                        Background="{TemplateBinding Background}"
                        Clip="{TemplateBinding ContentClip}"/>
              </Border>
            </AdornerDecorator>
            <Border CornerRadius="{TemplateBinding UniformCornerRadius, Converter={x:Static converters:DoubleToCornerRadiusConverter.Instance}}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}">
              <Border x:Name="PART_ClipBorder"
                      Padding="{TemplateBinding Padding}"
                      Background="{TemplateBinding Background}"
                      Clip="{TemplateBinding ContentClip}">
                <ContentPresenter x:Name="ContentPresenter"
                                  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                  Content="{TemplateBinding ContentControl.Content}"
                                  ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
                                  ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
                                  ContentTemplateSelector="{TemplateBinding ContentControl.ContentTemplateSelector}" />
              </Border>
            </Border>
          </Grid>

SandyHoDsal avatar Aug 20 '24 03:08 SandyHoDsal

@SandyHoDsal your suggested change removes the ClearType of text inside of the card. The duplicate border was added on purpose (see PR #3500) to maintain ClearType.

If you look closely, the right cards content (which has your changes applied) is a bit blurry: image

I also can't reproduce your problem. The cards in my demo app (v5.1.0) look fine: image

corvinsz avatar Aug 23 '24 13:08 corvinsz

Thanks for you reply.

My colleague got the same issue happens as well. But by adding one more border, you can see the screenshot below from my IDE, it shows the upper border will cover the one that with the name: PART_ClipBorder (which match the Card.cs).

Screenshot 2024-08-26 115113 Screenshot 2024-08-26 115053

SandyHoDsal avatar Aug 26 '24 07:08 SandyHoDsal

@SandyHoDsal your observations do not match with mine. I am using the latest version of the master branch without any modifications to the library. With the BorderThickness, UniformCornerRadius and Padding applied to a card like this:

<materialDesign:Card Width="200"
                     BorderThickness="5"
                     UniformCornerRadius="10"
                     Padding="0"
                     Background="{DynamicResource PrimaryHueDarkBrush}"
                     Foreground="{DynamicResource PrimaryHueDarkForegroundBrush}">

I get the following result: image

Notice how the UniformCornerRadius = 10 is also applied to the "inner" border, as it should be.

Is there anything else you apply to your cards or do different? Also just to double check, are you using the latest version of this library?

corvinsz avatar Aug 26 '24 13:08 corvinsz

Yes, I do cloned the latest version. And i do not modify any code and i am using vs2022 for the IDE. The above screenshot is capture without any modification to the Library, i only change the border properties

SandyHoDsal avatar Aug 27 '24 07:08 SandyHoDsal