When to make a user control using expression blend

2019-07-19 05:57发布

问题:

So I am working on a new app and I am using Expression Blend (for the first time) to create the layout and styles etc. but I have a question about when I would want to create a user control.

I have a borer that I want to use as the background for lots of stuff, however it is really a border in a border - then we will drop whatever controls into it. I want to reuse this of course, what is the best way to do that. I am thinking I want to make it into a user control?

The problem is unlike a standard border - I can't just edit a style in a resource dictionary because like I said - it's a border in a border.

Thanks in advance.

回答1:

Here is a UserControl example that allows for UIElement content:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Markup;

namespace TestClean.UserControls
{
    [ContentProperty("Child")]
    public partial class CustomBorder : UserControl
    {
        public static readonly DependencyProperty ChildProperty =
                DependencyProperty.Register("Child", typeof(UIElement), typeof(CustomBorder), new UIPropertyMetadata(null));
        public UIElement Child
        {
            get { return (UIElement)GetValue(ChildProperty); }
            set { SetValue(ChildProperty, value); }
        }

        public CustomBorder()
        {
            InitializeComponent();
        }
    }
}
<UserControl x:Class="TestClean.UserControls.CustomBorder"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             Name="control">
    <Border BorderThickness="1" CornerRadius="10" BorderBrush="Red" Background="Pink" Padding="5">
        <Border BorderThickness="1" CornerRadius="8" BorderBrush="Blue" Background="LightBlue" Padding="5">
            <ContentPresenter Content="{Binding ElementName=control, Path=Child}" />
        </Border>
    </Border>
</UserControl>

Usage example:

<uc:CustomBorder>
    <TextBlock Text="Lorem Ipsum"/>
</uc:CustomBorder>

Looks like:

Just modify the borders at will.


Edit: To actually answer the question and somewhat reiterate what i said in a comment to Tim's answer, UserControls are appropriate for this since they directly encapsulate the visual representation and allow for composition while not requiring much custom logic (in theory they can be very complex though and include a lot of logic). They are more lightweight and immediate than CustomControls.

In WPF controls (i.e. normal controls, including CustomControls which just inherit from them) are considered to be lookless, they normally provide a default template but their key aspect is their functionality, if you think of a ComboBox for example, it's a control which contains items, it should have one or no selected element and there should be a dropdown which displays the items and supports selection etc. It is the responsibility of the control to provide the necessary properties and methods which make up this functionality. Since this sometimes requires certain visual elements to exist controls can define parts which represent the minimal interface to the front-end.

Have a look at the Control Authoring overview, it is more in-depth and probably explains a lot of things better than i can.


Also: The ultimate lightweight method is only using Templates:

<!-- You can use any resource dictionary, specifying it in App.xaml
     simply makes it usable all over the application. -->
<Application.Resources>
    <ControlTemplate x:Key="CustomBorderTemplate" TargetType="{x:Type ContentControl}">
        <Border BorderThickness="1" CornerRadius="10" BorderBrush="Red" Background="Pink" Padding="5">
            <Border BorderThickness="1" CornerRadius="8" BorderBrush="Blue" Background="LightBlue" Padding="5">
                <ContentPresenter Content="{TemplateBinding Content}" />
            </Border>
        </Border>
    </ControlTemplate>
</Application.Resources>
<ContentControl Template="{StaticResource CustomBorderTemplate}">
    <TextBlock Text="Lorem Ipsum"/>
</ContentControl>

This yields the same result as the UserControl.



回答2:

You'd probably be better off not making a UserControl and instead making a Custom Control that derives from ContentControl or something similar - I say this because you're planning on having it contain other controls and that's a lot easier to do with Custom Controls than UserControls.