Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
How To: Subclass User Control
Message
From
06/05/2011 16:40:54
 
 
General information
Forum:
ASP.NET
Category:
Windows Presentation Foundation (WPF)
Miscellaneous
Thread ID:
01470880
Message ID:
01509896
Views:
38
>>>Hi,
>>>To just answer the question: Since you can't have XAML you would have to do it in code. e.g:
public _ViewBase()
>>>        {
>>>            StackPanel sp = new StackPanel();
>>>            Button b = new Button();
>>>            b.Content = "Click me";
>>>            sp.Children.Add(b);
>>>            this.Content = sp;
>>>        }
>>>But I agree with John - from a WPF POV this is very unlikely to be the right approach. Are you using MVVM for this app?
>>
>>I don't think that would work. As soon as you add content to the UserControl it's going to replace your stack panel.
>>
>>You could do it with view injection.
>>
>>* Wait till the control is fully loaded.
>>* Detach the contents.
>>* Add your wrapper.
>>* Attach the contents to your wrapper.
>>
>>But I don't recommend that either.
>
>Another way ( I don't recommend this either :-} ) might be something like:
namespace Junk
>{
>    public class _ViewBase : UserControl
>    {
>        public Grid G { get; set; }
>
>        public _ViewBase()
>        {
>            G = new Grid();
>            G.RowDefinitions.Add(new RowDefinition());
>            G.RowDefinitions.Add(new RowDefinition());
>            Button b = new Button();
>            b.Content = "Base Class Button";
>            b.SetValue(Grid.RowProperty, 0);
>            G.Children.Add(b);
>            this.Content = G;
>        }
>
>        public ContentControl AddedContent
>        {
>            get { return (ContentControl)GetValue(AddedContentProperty); }
>            set { SetValue(AddedContentProperty, value); }
>        }
>        static readonly PropertyMetadata m = new FrameworkPropertyMetadata(null, SetContent);
>
>        public static readonly DependencyProperty AddedContentProperty =
>            DependencyProperty.Register("AddedContent", typeof(ContentControl), typeof(_ViewBase), m);
>
>        private static void SetContent(DependencyObject d, DependencyPropertyChangedEventArgs e)
>        {
>            _ViewBase v = (_ViewBase)d;
>            ContentControl c = (ContentControl)e.NewValue;
>            c.SetValue(Grid.RowProperty, 1);
>            ((_ViewBase)d).G.Children.Add(c);
>         }
>     }
>}
Then
<Window x:Class="Junk.MainWindow"
>        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
>        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>        xmlns:local="clr-namespace:Junk">
>    < Window.Resources >
>        < ContentControl x:Key="Content" >
>            < StackPanel >
>                < Button >This is the added button< /Button >
>            < /StackPanel >
>        < /ContentControl >
>    < /Window.Resources >
>    < local:_ViewBase AddedContent="{StaticResource Content}" / >
>< /Window >
>Note to Michel (if you see this): The above XAML does not display correctly unless white space is added ??

That's better. LOL

I guess we should be nice and show the correct way:

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:WpfApplication2">

  < Style TargetType="{x:Type local:ButtonWrapper}">
    < Setter Property="Template">
      < Setter.Value>
        < ControlTemplate TargetType="{x:Type local:ButtonWrapper}">
          < Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
            < StackPanel>
              < Border Margin="3" Padding="3" BorderThickness="1" BorderBrush="Black">
                < ContentPresenter />
              < /Border>
              < Button Margin="3" Command="{TemplateBinding Command}">Test< /Button>
            < /StackPanel>
          < /Border>
        < /ControlTemplate>
      < /Setter.Value>
    < /Setter>
  < /Style>
< /ResourceDictionary>
ButtonWrapper.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace WpfApplication2
  {
  public class ButtonWrapper : ContentControl
    {
    public ICommand Command 
      {
      get { return (ICommand)GetValue(CommandProperty); }
      set { SetValue(CommandProperty, value); }
      }

    public static readonly DependencyProperty CommandProperty =
        DependencyProperty.Register("Command", typeof(ICommand), typeof(ButtonWrapper), new UIPropertyMetadata(null));

    static ButtonWrapper()
      {
      DefaultStyleKeyProperty.OverrideMetadata(typeof(ButtonWrapper), new FrameworkPropertyMetadata(typeof(ButtonWrapper)));
      }
    }
  }
Then use it like this:
    <local:ButtonWrapper Command="{Binding Path=TestCommand}">
      <TextBlock>This is the content.</TextBlock>
    </local:ButtonWrapper>
Previous
Reply
Map
View

Click here to load this message in the networking platform