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 如何在具有角半径的边框内设置控件的样式_Wpf - Fatal编程技术网

Wpf 如何在具有角半径的边框内设置控件的样式

Wpf 如何在具有角半径的边框内设置控件的样式,wpf,Wpf,我有一个简单的窗口,它包含一个带圆角半径的外边框和一个带背景的内边框。边框基本上只是我想放在圆角外部边框内的任何类型内容的占位符 <Window x:Class="TestRunner.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

我有一个简单的窗口,它包含一个带圆角半径的外边框和一个带背景的内边框。边框基本上只是我想放在圆角外部边框内的任何类型内容的占位符

<Window x:Class="TestRunner.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" AllowsTransparency="True" 
        WindowStyle="None" Background="{x:Null}" >
    <Border BorderThickness="2" BorderBrush="Black" CornerRadius="8"  >     
           <Border Background="White">

           </Border>
    </Border>
</Window>

问题是内部控件不继承圆角,因此它在圆角的顶部绘制,如下所示:

如何调整外部控件,使内部控件不会试图在圆角顶部绘制


在内部控件上设置圆角不是一个可行的选项,因为它会导致可怕的圆角半径重复。

我假设您在
边框内有一个
边框
,只是为了说明问题。如果可能的话,只需在外部
边框
中不包含任何在角落中呈现任何内容的控件,就可以完全避免这个问题

如果必须包含一个在角落中渲染某些内容的控件,则可以使用
剪辑

<Border x:Name="border" CornerRadius="10">
    <Border.Clip>
        <RectangleGeometry Width="{Binding ActualWidth, ElementName=border}" Height="{Binding ActualHeight, ElementName=border}" RadiusX="10" RadiusY="10"/>
    </Border.Clip>

    <Border Background="White"/>
</Border>

一种可能是在外边框上添加一些填充物:

<Border BorderThickness="2" BorderBrush="Black" CornerRadius="8" Padding="4">
    ....
</Border>

....

但这可能会导致应用程序中出现过多的空白。

矩形几何体
没有宽度属性,至少在WPF中是这样

为了满足我的需要,我必须创建一个
IMultiValueConverter
,如下所述:

在那之后,我在拐角处仍然有一个问题,所以我使用了Kent的第二个解决方案(注意,
Border.Fill
也不存在)

以下是我写的一篇文章:

<Grid>
    <Border x:Name="canvasBorder" CornerRadius="5">
        <Border.Resources>
            <tools:ContentClipConverter x:Key="ContentClipConverter" />
        </Border.Resources>
        <Border.Clip>
            <MultiBinding Converter="{StaticResource ContentClipConverter}">
                <Binding Path="ActualWidth"
                RelativeSource="{RelativeSource Self}"/>
                <Binding Path="ActualHeight"
                RelativeSource="{RelativeSource Self}"/>
                <Binding Path="CornerRadius"
                RelativeSource="{RelativeSource Self}"/>
            </MultiBinding>
        </Border.Clip>
        <!-- ... -->
    </Border>
    <Border BorderBrush="Black" BorderThickness="1" CornerRadius="5" Background="Transparent" IsHitTestVisible="false" />
</Grid>

在ContentClipConverter.cs中:

/// <summary>
/// Clips the content of a rounded corner border.
/// Code taken from <a href="https://stackoverflow.com/a/5650367/2663813">this topic</a>
/// </summary>
public class ContentClipConverter : IMultiValueConverter {
    /// <summary>
    /// Gets a clipping geometry for the item
    /// </summary>
    /// <param name="values">The input values</param>
    /// <param name="targetType">The parameter is not used.</param>
    /// <param name="parameter">The parameter is not used.</param>
    /// <param name="culture">The parameter is not used.</param>
    /// <returns>The clipping geometry</returns>
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
        if (values.Length == 3 && values[0] is double && values[1] is double && values[2] is CornerRadius) {
            var width = (double)values[0];
            var height = (double)values[1];

            if (width < double.Epsilon || height < double.Epsilon) {
                return Geometry.Empty;
            }

            var radius = (CornerRadius)values[2];

            // Actually we need more complex geometry, when CornerRadius has different values.
            // But let me not to take this into account, and simplify example for a common value.
            var clip = new RectangleGeometry(new Rect(0, 0, width, height), radius.TopLeft, radius.TopLeft);
            clip.Freeze();

            return clip;
        }

        return DependencyProperty.UnsetValue;
    }

    /// <summary>
    /// Not implemented
    /// </summary>
    /// <param name="value">The parameter is not used.</param>
    /// <param name="targetTypes">The parameter is not used.</param>
    /// <param name="parameter">The parameter is not used.</param>
    /// <param name="culture">The parameter is not used.</param>
    /// <returns>This function does not return anything</returns>
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
        throw new NotSupportedException();
    }
//
///剪辑圆角边框的内容。
///代码取自
/// 
公共类ContentClipConverter:IMultiValueConverter{
/// 
///获取项的剪裁几何体
/// 
///输入值
///未使用该参数。
///未使用该参数。
///未使用该参数。
///裁剪几何体
公共对象转换(对象[]值,类型targetType,对象参数,CultureInfo区域性){
如果(values.Length==3&&values[0]是double&&values[1]是double&&values[2]是CornerRadius){
变量宽度=(双)值[0];
变量高度=(双)值[1];
if(宽度<双ε|高度<双ε){
返回几何体。空;
}
变量半径=(拐角半径)值[2];
//实际上,当拐角半径有不同的值时,我们需要更复杂的几何体。
//但我不想把这一点考虑进去,而要简化这个例子,以获得一个共同的价值。
var clip=新矩形几何体(新矩形(0,0,宽度,高度),radius.TopLeft,radius.TopLeft);
clip.Freeze();
回程夹;
}
返回dependencProperty.unset值;
}
/// 
///未实施
/// 
///未使用该参数。
///未使用该参数。
///未使用该参数。
///未使用该参数。
///此函数不返回任何内容
公共对象[]转换回(对象值,类型[]目标类型,对象参数,CultureInfo区域性){
抛出新的NotSupportedException();
}
/// <summary>
/// Clips the content of a rounded corner border.
/// Code taken from <a href="https://stackoverflow.com/a/5650367/2663813">this topic</a>
/// </summary>
public class ContentClipConverter : IMultiValueConverter {
    /// <summary>
    /// Gets a clipping geometry for the item
    /// </summary>
    /// <param name="values">The input values</param>
    /// <param name="targetType">The parameter is not used.</param>
    /// <param name="parameter">The parameter is not used.</param>
    /// <param name="culture">The parameter is not used.</param>
    /// <returns>The clipping geometry</returns>
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
        if (values.Length == 3 && values[0] is double && values[1] is double && values[2] is CornerRadius) {
            var width = (double)values[0];
            var height = (double)values[1];

            if (width < double.Epsilon || height < double.Epsilon) {
                return Geometry.Empty;
            }

            var radius = (CornerRadius)values[2];

            // Actually we need more complex geometry, when CornerRadius has different values.
            // But let me not to take this into account, and simplify example for a common value.
            var clip = new RectangleGeometry(new Rect(0, 0, width, height), radius.TopLeft, radius.TopLeft);
            clip.Freeze();

            return clip;
        }

        return DependencyProperty.UnsetValue;
    }

    /// <summary>
    /// Not implemented
    /// </summary>
    /// <param name="value">The parameter is not used.</param>
    /// <param name="targetTypes">The parameter is not used.</param>
    /// <param name="parameter">The parameter is not used.</param>
    /// <param name="culture">The parameter is not used.</param>
    /// <returns>This function does not return anything</returns>
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
        throw new NotSupportedException();
    }