5680

WPF custom control and direct content support

Question:

I am fairly new to WPF, and am a bit stuck, so any help would be appreciated.

I am trying to write WPF custom control that encapsulates several elements of functionality that I already having working (i.e sorting, filtering, standard menus, etc.), but in a nice neat package to avoid repetition.

Anyway I have created the custom control (based on control), and then have the following in the 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:Controls.ListViewExtended"> <Style TargetType="{x:Type local:ListViewExtended}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:ListViewExtended}"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <ListView> <ListView.View> <GridView> <!-- Content goes here --> </GridView> </ListView.View> </ListView> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>

When I try to add GridViewColumns (or any control really), as below ...

<elv:ListViewExtended> <GridView> <GridViewColumn Width="140" Header="Column 1" /> <GridViewColumn Width="140" Header="Column 2" /> <GridViewColumn Width="140" Header="Column 3" /> </GridView> </elv:ListViewExtended>

I get the <em>"... does not support direct content"</em> error.

I have created a dependancy property (again below) that allows the adding of GridView, but it still doesn't work.

public static DependencyProperty GridViewProperty; public static string GridViewHeader(DependencyObject target) { return (string)target.GetValue(GridViewProperty); } public static void GridViewHeader(DependencyObject target, string value) { target.SetValue(GridViewProperty, value); }

Thanks in advance

Answer1:

Inherit your custom control from the ListView, not from the Control. This would definitely cause you to change the template, but I encourage you to read more documentation on how to do it (e.g. Sacha Barber's article: <a href="http://www.codeproject.com/KB/WPF/WPF_CustomerControl.aspx" rel="nofollow">Creating and consuming a custom WPF control</a>).

Good luck in your learning!

Answer2:

All You need is to specify ContentPropertyAttribute.

[ContentProperty("MainContent")] public class GroupPanel : Control { public GroupPanel() { DefaultStyleKey = typeof(GroupPanel); } public object MainContent { get { return GetValue(MainContentProperty); } set { SetValue(MainContentProperty, value); } } public static readonly DependencyProperty MainContentProperty = DependencyProperty.Register("MainContent", typeof(object), typeof(GroupPanel), null); }

Reference: <a href="http://msdn.microsoft.com/en-us/library/system.windows.markup.contentpropertyattribute%28v=vs.90%29.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/system.windows.markup.contentpropertyattribute(v=vs.90).aspx</a>

Answer3:

I use this simple solution in our projects to support direct content in custom controls:

Add a "CustomControl" to your project and derive this control from class "UserControl" instead of "Control":

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

When you add a CustomControl to your project, Visual Studio (I am using 2012) automatically adds a folder "Themes" including a file named "Generic.xaml". This file holds a ResourceDictionary to define the style (template) of your CustomControl.

You will find a basic template for your CustomControl, already used as DefaultStyle. For direct content support place a ContentPresenter somewhere inside this template with parent content binding:

<Style TargetType="{x:Type local:MyCustomControl}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:MyCustomControl}"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <ContentPresenter Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" /> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>

Now it's possible to add content to your CustomControl:

<Window x:Class="MyApplication.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:MyApplication" Title="MainWindow" Height="350" Width="525"> <Grid> <controls:MyCustomControl> <TextBlock>Hello</TextBlock> </controls:MyCustomControl> </Grid> </Window>

Hope this helps!

Recommend

  • Setting margin programmatically to CardView
  • German number separators using format language on OSX?
  • Active Directory Federation Services Logout
  • Parsing JSON to custom ArrayList, only returning last item?
  • determine if drive is removable (flash or HDD) knowing only the drive letter
  • C# mvc3 redirect sitemap.xml to controller action
  • hadoop jar command points to local filesystem
  • Get Element By Classname Script Not Working
  • JSF with Enum 'Validation Error: Value is not valid'
  • Joining across databases with dbplyr
  • API Gateway Encoding multipart/form-data
  • Arc gradients in Flutter?
  • MVC3 Extension for ValidatorMessage
  • Java 11 and E(fx)clipse JavaFX plugin on Eclipse 4.9: An error has occurred - see the log file
  • Dynamically change JavaFX css property
  • android : speech recognition what are the technologies available
  • $this->a->b->c->d calling methods from a superclass in php
  • GTK3 + OpenGL for windows: multiple GtkGLArea (ie. OpenGL contexts)
  • Java Collections.shuffle() weird behaviour [closed]
  • Compiling multiple source files in Rcpp
  • Annotate objects in a queryset with next and previous object ids
  • Floating parent div grows to hypothetical width of floating child div
  • Can a PHP script be scheduled to run at a specific time or after a specific amount of time has expir
  • how to run ejabberd with Erlang on Heroku?
  • How to specify generic type when the type is only known at runtime?
  • reshape/remould data frame to create normalized bar chart and pie chart
  • How to integrate angular2-material (alpha 8.2) with angular2-Quickstart app
  • read part of h5 dataset python
  • Send array to next viewcontroller iOs xcode [duplicate]
  • Comma decimal separator is ignored by ASP.NET MVC model binder
  • calling IO Operations from thread in ruby c extension will cause ruby to hang
  • Running R's aov() mixed effects model from Python using rpy2
  • How to check if object is null in Java?