2009-08-31 117 views
2

我必须开发一个wpf控件,它应该具有与众所周知的边框相同的行为。 控件的形状应该是新的部分。每个可定义的封闭路径应被用来定义控制的出现。WPF自由​​形式边框控件

我需要帮助来实现这一点。 目前我不知道如何与闭路径交换矩形(??)。

任何帮助将不胜感激。

回答

6

编辑这里直接回答你的问题。我们将编写一个ContentControl派生类,具有非常灵活的边界形式。这个想法的基础在于OpacityMask

如果您想了解更多关于此方法的信息,请参阅Chris Cavanagh's solution的圆角示例。

步骤1。创建自定义控制FreeFormContentControl:

FreeFormContentControl.cs

using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Media; 

namespace WpfApplication5 
{ 
    public class FreeFormContentControl : ContentControl 
    { 
    public Geometry FormGeometry 
    { 
     get { return (Geometry)GetValue(FormGeometryProperty); } 
     set { SetValue(FormGeometryProperty, value); } 
    } 

    public static readonly DependencyProperty FormGeometryProperty = 
     DependencyProperty.Register("FormGeometry", typeof(Geometry), typeof(FreeFormContentControl), new UIPropertyMetadata(null)); 

    static FreeFormContentControl() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(
     typeof(FreeFormContentControl), 
     new FrameworkPropertyMetadata(typeof(FreeFormContentControl)) 
     ); 
    } 
    } 
} 

主题\ Generic.xaml上自定义控件

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:local="clr-namespace:WpfApplication5"> 
    <Style TargetType="{x:Type local:FreeFormContentControl}"> 
    <Setter Property="FormGeometry" 
      Value="M0,0 L1,0 1,1 0,1z" /> 
    <Setter Property="Background" 
      Value="Black" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
     <ControlTemplate TargetType="{x:Type local:FreeFormContentControl}"> 
      <Grid> 
      <Path Name="mask" 
        Data="{TemplateBinding FormGeometry}" 
        Fill="{TemplateBinding Background}" /> 
      <Grid> 
       <Grid.OpacityMask> 
       <VisualBrush Visual="{Binding ElementName=mask}" /> 
       </Grid.OpacityMask> 
       <ContentPresenter /> 
      </Grid> 
      </Grid> 
     </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
    </Style> 
</ResourceDictionary> 

更多阅读可以CodeProject找到。

步骤2。用法。现在,您可以将任何内容放置在此控件中。它的默认形状是矩形。所以,下面的代码将导致经常StackPanel的UI:

<Window x:Class="WpfApplication5.Window1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:cc="clr-namespace:WpfApplication5" 
     Title="Window1" 
     Height="300" 
     Width="300"> 
    <Grid> 
    <cc:FreeFormContentControl> 
     <StackPanel> 
     <Button Content="Any" /> 
     <Button Content="Content" /> 
     <TextBlock Text="Goes" /> 
     <TextBox Text="Here" /> 
     </StackPanel> 
    </cc:FreeFormContentControl> 
    </Grid> 
</Window> 

但是,如果你定义自定义FormGeometry你会得到自定义形状。例如,下面的表格几何呈现内控制金刚石内:

<cc:FreeFormContentControl FormGeometry="M0,0.5 L0.5,0 1,0.5 0.5,1z"> 

要详细了解几何定义从XAML,读取对应部分上MSDN:Path Markup Syntax

这里最后提到的一点是,您不必指定或计算FormGeomtry的具体像素值。网格使这个技巧成为可能。所以想想它的百分比。即1 ==全宽或高度。 0.5 ==可用宽度/高度的一半等等。

希望这会有所帮助。

+0

嗨Anvaka,感谢您的答案。 我想我不能使用你的解决方案,因为只有视觉部分受到影响。我需要一个支持ContentPresenter功能的解决方案。 – 2009-09-01 07:56:30

+0

确实可以。将此代码封装到自定义控件中。从ContentControl派生它。公开一个名为“BorderGeometry”的依赖项属性。并在控件的模板中绑定“掩码”路径。即你会在你的模板里有这样的东西:。 – Anvaka 2009-09-01 08:30:05

+0

我Anvaka,再次感谢。 我明白你的意思,并确定它的工作原理。 “Costum Control”和“mask”是我寻找的正确关键词。 不幸的是,我从来没有写过自定义控件,这就是为什么我现在必须阅读一些理论的东西。 (也许你有简单的代码示例??) CU斯科特 – 2009-09-01 12:26:01