开发者

WPF - How can I pass in other controls into my UserControl?

Basically, I wan开发者_JS百科t my UserControl to be able to take in a type of ItemsControl so that my XAML can look like this:

<my:MyControl DataContext="{Binding InnerViewModel}">
    <ItemsControl ... />
</my:MyControl>

That way, the MyControl displays the custom Items control along with other controls?


A couple of notes first:

  1. A UserControl is a type of ContentControl. This means that you can not pass a child element into the UserControl. You can override the content, but that would be fruitless for what you want to accomplish.
  2. If you want a control that contains a SINGLE child element, you're looking for a Decorator class.
  3. If you want a control that contains MULTIPLE child elements, you're looking for a ItemsControl class.

So, basically you're doing it incorrectly. That being said, there are a couple of ways of accomplishing what you want. You could simply use an ItemsControl and override the Template with your own template. You could also create a CustomControl that inherits from ItemsControl or Decorator.

Overriding the template (as a style) will be the easier way to do it, so my suggestion is to do that, unless you're very well-versed in how to create a WPF custom control properly.

If you opt to go for a custom control, it looks like you're probably going to want to do so as a Decorator (just guessing that you'd want a single child here). The annoying part is that to truly create a well-written WPF custom control you'll have to have some really good skills. For example, Border is a type of Decorator that contains a few DependencyProperty properties. The template ships with the PresentationFramework.dll (I think) so that it has some default look-and-feel to it. A border (custom control) is not that difficult to write. What gets very annoying is when you want to actually have interaction logic. You'll need to put in checks and balances to ensure that you retrieve the control references from the template. Then, and only then, if the references are not null can you proceed onto your logic. Basically, say you wrote a type of custom control that has 2 buttons to perform logic, and you provided a default template where the buttons are named "Button 1" and "Button 2". You can't just pull Button 1 and Button 2 from the template and expect them to be there; someone could easily override your default template and remove Button 1 and Button 2, rendering your custom control useless (pretty much). What makes it terrible is if you coded without accounting for these situations. You're custom control will run into NullReferenceExceptions. Not to mention that you'll have to wire things up to allow for command binding PER button and you should also provide a routedevent for each button. Basically, a custom control might be a bit too much for what you want to do (possibly).

I could be wrong, you might be super skilled and know how to crank out custom controls. Or, better yet, you might have just wanted a simple way to decorate your ItemsControl by say, adding a banner to the top of it? I don't know, but I'm sure you do :)


Overall, I'd look at how to override the ItemsControl template. Here's a sample:

<Window x:Class="Sample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="640" Height="480">
    <Window.Resources>
        <Style x:Key="ItemsControlStyle1" TargetType="{x:Type ItemsControl}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ItemsControl}">
                        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                            <StackPanel Orientation="Vertical">
                                <TextBlock Text="A HEADER!" />
                                <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                            </StackPanel>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

    <Grid x:Name="LayoutRoot">
        <ItemsControl Style="{DynamicResource ItemsControlStyle1}" />
    </Grid>
</Window>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜