模板面板,自定义外观

时间:2014-08-27 09:34:59

标签: c# wpf templates controls panel

我尝试使用模板创建自定义面板。至少尝试。我知道Panel没有模板但是我需要在该Panel上应用角半径,阴影和背景。我正在寻找解决方案,但我找不到任何可以帮助我的方法。

XAML代码

<Style TargetType="{x:Type local:SupremeCard}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:SupremeCard}">
                <local:ClippingBorder CornerRadius="1" Background="{TemplateBinding Background}">
                    <local:ClippingBorder.Effect>
                        <DropShadowEffect BlurRadius="5" ShadowDepth="1" Direction="270" Color="#CCCCCC" Opacity="1"/>
                    </local:ClippingBorder.Effect>
                    <Grid x:Name="MainContainer"></Grid>
                </local:ClippingBorder>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

当前代码

public class SupremeCard : Control
{
    static SupremeCard()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(SupremeCard), new FrameworkPropertyMetadata(typeof(SupremeCard)));
    }
}

基本上你可以看到我什么都没有。尝试将SupremeCard转换为Panel,但我无法修改它的外观。试图在SupremeCard(作为控制)和儿童中实现一个网格,但是在掉落并放置在&#34;面板&#34;物品正在消失或投掷&#34;无法创建物体实例&#34;例外。

之前的代码:

[DesignTimeVisibleAttribute()]
[TemplatePart(Name = "MainContainer", Type = typeof(Grid))]
public class SupremeCard : Control
{
    public ObservableCollection<UIElement> Children { get; private set; }

    private Grid MainContainer { get; set; }

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

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        MainContainer = base.Template.FindName("MainContainer", this) as Grid;
    }

    public SupremeCard()
    {
        Children = new ObservableCollection<UIElement>();

        Children.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Children_CollectionChanged);
    }

    void Children_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        switch (e.Action)
        {
            case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
                foreach (UIElement elem in e.NewItems)
                {
                    MainContainer.Children.Add(elem);
                }

                break;
            case System.Collections.Specialized.NotifyCollectionChangedAction.Move:
                break;
            case System.Collections.Specialized.NotifyCollectionChangedAction.Remove:

                foreach (UIElement elem in e.OldItems)
                {
                    MainContainer.Children.Remove(elem);
                }
                break;
            case System.Collections.Specialized.NotifyCollectionChangedAction.Replace:
                break;
            case System.Collections.Specialized.NotifyCollectionChangedAction.Reset:
                break;
            default:
                break;
        }
    }
}

对于相同的XAML构造。有什么帮助吗?

1 个答案:

答案 0 :(得分:1)

默认情况下,WPF中的

Panel没有外观。如果您想让Panel有一个白色Background,那么您只需将其Background属性设置为White

<StackPanel Background="White">
    ...
</StackPanel>

如果你想让它有阴影,那么只需添加一个:

在资源中:

<DropShadowEffect x:Key="Shadow" BlurRadius="10" Direction="270" ShadowDepth="7" 
    Opacity="0.5" />

...

<StackPanel Background="White" Effect="{StaticResource Shadow}">
    ...
</StackPanel>

请不要认为WPF与WinForms类似,因为它是非常不同的。我们经常不得不在WinForms中创建新的控件有很多原因,但WPF根本不是这样的。事实上,在使用WPF时,没有理由创建新控件,因为我们可以使用Style调整标准控件,甚至可以定义新的ControlTemplate

我认为您可以通过阅读MSDN上的Control Authoring Overview页面来了解WPF的可能性。


更新&gt;&gt;&gt;

  

我在设置圆角半径方面遇到了问题(比如在边框中)。

正如我一直告诉你的那样...... Panel默认情况下没有外观,所以你可以把它添加到另一个控件中来看看:

<Border BorderBrush="Black" BorderThickness="1" CornerRadius="5" Background="White" 
    Effect="{StaticResource Shadow}">
    <StackPanel>
        ...
    </StackPanel>
</Border>