Click here to Skip to main content
Click here to Skip to main content

Creating and consuming a custom WPF control

By , 1 Mar 2007
 

Introduction

Whenever a new technology comes along, I personally find that the best way to get to grips with its functionality is to try and create something you have done in another language. To this end, this article will describe how to create a custom control in WPF which will raise custom events. The custom control will then be placed with a standard XAML window and the custom control's events shall be subscribed to. That's it in a nutshell. But along the way there are several things that I would like to point out to you.

The proposed structure will be as follows:

  • A word on XAML / WPF
  • The custom Control Itself
  • A word on events in .NET 3.0
  • Referencing an external custom control in an XAML window
  • Where is the InitializeComponent() method anyway
  • A screen shot of the demo app

A Word On XAML / WPF

WPF applications are quite similar is one sense to ASP.NET applications; there may (or may not) be an XAML file, and also a code behind file where the XAML file contains the windows / control rendering, and the code behind does all the procedural code. This is one development model. But there is another way. Anything that can be done in XAML can also be done entirely in code behind (C#/ VB). To this end the custom control that I've created is entirely code created. As for this example it just seemed to make more sense.

The Custom Control Itself

As color pickers seem to be almost universally popular at codeproject, I thought let's do one of them. This is a single control that has been created in a separate Visual Studio 2005 project, and is part of the whole solution. I have done this as it is the most common way that we all use third party controls. We get a DLL and make a reference to it. In fact I have chosen this path, as the XAML directives to reference a control do vary slightly depending on whether it is an internal class, or an external DLL. Most commonly I thought it would be a third party external DLL that was being referenced. If you don't get this, don't worry. There will be more on it later.

So without further ado, let's look at the code:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace ColorPicker
{
    #region ColorPickerControl CLASS
    /// <summary>
    /// A simple color picker control, with a custom event that uses
    /// the standard RoutedEventArgs.
    /// <br/>
    /// NOTE: I also tried to create a custom event with custom inherited
    /// RoutedEventArgs, but this didn't seem to work, 
    /// so this event is commented out. But if anyone knows how to do this 
    /// please let me know, as far as I know
    /// I am doing everything correctly
    /// </summary>
    public class ColorPickerControl : ListBox
    {
        #region InstanceFields
        //A RoutedEvent using standard RoutedEventArgs, event declaration
        //The actual event routing
        public static readonly RoutedEvent NewColorEvent =
            EventManager.RegisterRoutedEvent
        ("NewColor", RoutingStrategy.Bubble,
                   typeof(RoutedEventHandler), typeof(ColorPickerControl));

        //A RoutedEvent using standard custom ColorRoutedEventArgs, 
        //event declaration

        ////the event handler delegate
        public delegate void NewColorCustomEventHandler
            (object sender, ColorRoutedEventArgs e);

        ////The actual event routing
        public static readonly RoutedEvent NewColorCustomEvent =
             EventManager.RegisterRoutedEvent
        ("NewColorCustom", RoutingStrategy.Bubble,
                   typeof(NewColorCustomEventHandler), 
        typeof(ColorPickerControl));
        //******************************************************************
        //string array or colors
        private string[] _sColors =
        {
            "Black", "Brown", "DarkGreen", "MidnightBlue",
                "Navy", "DarkBlue", "Indigo", "DimGray",
            "DarkRed", "OrangeRed", "Olive", "Green",
                "Teal", "Blue", "SlateGray", "Gray",
            "Red", "Orange", "YellowGreen", "SeaGreen",
                "Aqua", "LightBlue", "Violet", "DarkGray",
            "Pink", "Gold", "Yellow", "Lime",
                "Turquoise", "SkyBlue", "Plum", "LightGray",
            "LightPink", "Tan", "LightYellow", "LightGreen",
                "LightCyan", "LightSkyBlue", "Lavender", "White"
        };
        #endregion
        #region Constructor
        /// <summary>
        /// Constructor for ColorPickerControl, which is a ListBox subclass
        /// </summary>
        public ColorPickerControl()
        {
            // Define a template for the Items, 
            // used the lazy FrameworkElementFactory method
            FrameworkElementFactory fGrid = new
                FrameworkElementFactory
        (typeof(System.Windows.Controls.Primitives.UniformGrid));
            fGrid.SetValue
       (System.Windows.Controls.Primitives.UniformGrid.ColumnsProperty,10);
            // update the ListBox ItemsPanel with the new 
            // ItemsPanelTemplate just created
            ItemsPanel = new ItemsPanelTemplate(fGrid);

            // Create individual items
            foreach (string clr in _sColors)
            {
                // Creat bounding rectangle for items data
                Rectangle rItem = new Rectangle();
                rItem.Width = 10;
                rItem.Height = 10;
                rItem.Margin = new Thickness(1);
                rItem.Fill = 
            (Brush)typeof(Brushes).GetProperty(clr).GetValue(null, null);
                //add rectangle to ListBox Items
                Items.Add(rItem);

                //add a tooltip
                ToolTip t = new ToolTip();
                t.Content = clr;
                rItem.ToolTip = t;
            }
            //Indicate that SelectedValue is Fill property of Rectangle item.
            //Kind of like an XPath query, 
            //this is the string name of the property
            //to use as the selected item value from the actual item data. 
            //The item data being a Rectangle in this case
            SelectedValuePath = "Fill";
        }
        #endregion
        #region Events
        // Provide CLR accessors for the event
        public event RoutedEventHandler NewColor
        {
            add { AddHandler(NewColorEvent, value); }
            remove { RemoveHandler(NewColorEvent, value); }
        }

        // This method raises the NewColor event
        private void RaiseNewColorEvent()
        {
            RoutedEventArgs newEventArgs = new RoutedEventArgs(NewColorEvent);
            RaiseEvent(newEventArgs);
        }

        // Provide CLR accessors for the event
        public event NewColorCustomEventHandler NewColorCustom
        {
            add { AddHandler(NewColorCustomEvent, value); }
            remove { RemoveHandler(NewColorCustomEvent, value); }
        }

        // This method raises the NewColorCustom event
        private void RaiseNewColorCustomEvent()
        {
            ToolTip t = (ToolTip)(SelectedItem as Rectangle).ToolTip;
            ColorRoutedEventArgs newEventArgs = 
        new ColorRoutedEventArgs(t.Content.ToString());
            newEventArgs.RoutedEvent = ColorPickerControl.NewColorCustomEvent;
            RaiseEvent(newEventArgs);
        }
        //*******************************************************************
        #endregion
        #region Overrides
        /// <summary>
        /// Overrides the OnSelectionChanged ListBox inherited method, and
        /// raises the NewColorEvent
        /// </summary>
        /// <param name="e">the event args</param>
        protected override void OnSelectionChanged(SelectionChangedEventArgs e)
        {
            base.OnSelectionChanged(e);
            //raise the event with standard RoutedEventArgs event args
            RaiseNewColorEvent();
            //raise the event with the custom ColorRoutedEventArgs event args
            RaiseNewColorCustomEvent();
            //****************************************************************
        }
        #endregion
    }
    #endregion
    #region ColorRoutedEventArgs CLASS
    /// <summary>
    /// ColorRoutedEventArgs : a custom event argument class
    /// </summary>
    public class ColorRoutedEventArgs : RoutedEventArgs
    {
        #region Instance fields
        private string _ColorName = "";
        #endregion
        #region Constructor
        /// <summary>
        /// Constructs a new ColorRoutedEventArgs object
        /// using the parameters provided
        /// </summary>
        /// <param name="clrName">the color name string</param>
        public ColorRoutedEventArgs(string clrName)
        {
            this._ColorName = clrName;
        }
        #endregion
        #region Public properties
        /// <summary>
        /// Gets the stored color name
        /// </summary>
        public string ColorName
        {
            get { return _ColorName; }
        }
        #endregion
    }
    #endregion
}

It can be seen that this is all fairly normal C# .NET 3.0 code (that is if you are OK with .NET 3.0 stuff, I am just learning). I want to pay some special attention to the constructor. Let's have a look at that part by part.

// Define a template for the Items, use the lazy FrameworkElementFactory
// method
FrameworkElementFactory fGrid = new FrameworkElementFactory
    (typeof(System.Windows.Controls.Primitives.UniformGrid));
    fGrid.SetValue
    (System.Windows.Controls.Primitives.UniformGrid.ColumnsProperty, 10);
//update the ListBox ItemsPanel with the new ItemsPanelTemplate just created
ItemsPanel = new ItemsPanelTemplate(fGrid);

The FrameworkElementFactory class is a way to programmatically create templates, which are subclasses of FrameworkTemplate such as ControlTemplate or DataTemplate. This is equivalent to creating a <ControlTemplate> tag in XAML markup. So what we are really doing here is saying that the internal inherited Listbox.ItemsPanel will have a template applied to it that will be a uniform grid layout with 10 columns.

// Create individual items
foreach (string clr in _sColors)
{
    // Create bounding rectangle for items data
    Rectangle rItem = new Rectangle();
    rItem.Width = 10;
    rItem.Height = 10;
    rItem.Margin = new Thickness(1);
    rItem.Fill = 
    (Brush)typeof(Brushes).GetProperty(clr).GetValue(null, null);
    //add rectangle to ListBox Items
    Items.Add(rItem);
    //add a tooltip
    ToolTip t = new ToolTip();
    t.Content = clr;
    rItem.ToolTip = t;
}

This section of the code is responsible for creating the individual ListItem contents. So what is going on? Well, the items are being created as Rectangle objects (yep that's right, Rectangles). Then the Rectangles are being filled with a Brush color, and then the Rectangle has a ToolTip applied.

//Indicate that SelectedValue is Fill property of Rectangle item.
//Kind of like an XPath query, this is the string name of the property
//to use as the selected item value from the actual item data. The item
//data being a Rectangle in this case
SelectedValuePath = "Fill";

Finally the SelectedValuePath is told that the property that should be mapped to the SelectedValue is "Fill". So this means that whenever we get the SelectedValue the object it will be is a Brush as default, as "Fill" is a Brush Type, unless it is cast to another object Type. Isn't that mental. WPF is mind blowing, it really is.

The more eagle eyed amongst you will notice that the code for the control contains 2 events one of which is commented out. More on this later.

A word on events in .NET 3.0

Microsoft being Microsoft didn't want us to get too comfortable with things, so they have overhauled everything it would appear. Even something as small as events, is no longer the same as it was in .NET 2.0.

The code snippets below represent the new .NET 3.0 way of creating events.

I have created a custom event called NewColorEvent so let's have a look at how to define an event:

//A RoutedEvent using standard RoutedEventArgs, event declaration
//The actual event routing
public static readonly RoutedEvent NewColorEvent =
          EventManager.RegisterRoutedEvent("NewColor", RoutingStrategy.Bubble,
            typeof(RoutedEventHandler), typeof(ColorPickerControl));

What else do we need to do, well we need to create the accessors for subscribing / unsubscribing to the event.

// Provide CLR accessors for the event
public event RoutedEventHandler NewColor
{
    add { AddHandler(NewColorEvent, value); }
    remove { RemoveHandler(NewColorEvent, value); }
}

And we also need a raise event method such as:

// This method raises the NewColor event
private void RaiseNewColorEvent()
{
     RoutedEventArgs newEventArgs = new RoutedEventArgs(NewColorEvent);
     RaiseEvent(newEventArgs);
}

And lastly we need to raise the event somewhere. I have chosen to do this in an override of the inherited ListBox OnSelectionChanged method; this is shown below:

//raise the event with standard RoutedEventArgs event args
RaiseNewColorEvent();

And that's all there is to creating a custom event in a custom control. We just need to place the control somewhere now and subscribe to this lovely new event.

Referencing an external custom control in an XAML window

OK so you think you know how to make a reference to a DLL which contains a custom control. You just create a new tab on the toolbar, and browse to the DLL and any of the contained controls to the toolbar. Right. Well that didn't seem to work. So what do you have to do. Is Add a project reference (right click on references) and browse to the assembly (DLL) with the custom control(s), only one in this articles case.

So that's step 1. Then we actually want to use the custom control within a XAML window. So we have to add an extra directive to the XAML Windows root element. The important part to add is as follows:

If using a code file that you have the source code for

xmlns:src="clr-namespace:NAMESPACE_NEEDED"

If using a external DLL

xmlns:src="clr-namespace:NAMESPACE_NEEDED;assembly=ASSEMBLYNAME_NEEDED"

So for the attached example, where we have an external DLL which has a control we need to use, the root element would be changed to the following:

<Window x:Class="ColorControlApp.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:src="clr-namespace:ColorPicker;assembly=ColorPickerControl"
    Title="ColorControlApp" Height="300" Width="300">

That's part of the story. We have now successfully referenced the external user control in the XAML, but we still don't have an instance of the control in the markup yet. So how do we do that. Well we do something like this:

<src:ColorPickerControl HorizontalAlignment="Center"
                        VerticalAlignment="Center" Name="lstColorPicker"/>

OK so now we have done the XAML part, but what about the code behind file. We still need to do that part. So how is that done. Well, luckily that part is easier. Its just a normal using statement we need:

using ColorPicker;

Where is the InitializeComponent() method anyway ?

Now we really do have a fully referenced external DLL, which contains a user control, which we now have an instance of within our XAML window, that is also now known about by the code behind logic because of the two steps just carried out.

But just how does the XAMLs code behind file know about the user control contained within the XAML file. Well the answer to that, is that when Visual Studio compiles a project, it creates a new generated source file, which is placed into the DEBUG\OBJ or RELEASE\OBJ (depends on how you are compiling the project). This file is called the same as the current XAML window file, but the extension will be g.cs for c# or g.vb for VB.

The following screen print shows this for the attached project:

Can you see there is a Window1.g.cs (as I use C#) file there.

So what is that all about. Well let's have a look.

//---------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.42
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//---------------------------------------------------------------------------

using ColorPicker;
using System;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;
using System.Windows.Media.TextFormatting;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ColorControlApp 
{
    /// <summary>
    /// Window1
    /// </summary>
    public partial class Window1 : 
    System.Windows.Window, System.Windows.Markup.IComponentConnector 
    {
        internal System.Windows.Controls.StackPanel Stack;
        internal System.Windows.Controls.Label lblColor;
        internal ColorPicker.ColorPickerControl lstColorPicker;


        private bool _contentLoaded;
        /// <summary>
        /// InitializeComponent
        /// </summary>
        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public void InitializeComponent() 
        {
            if (_contentLoaded) 
            {
                return;
            }
            _contentLoaded = true;
            System.Uri resourceLocater = 
            new System.Uri("/ColorControlApp;component/window1.xaml", 
            System.UriKind.Relative);
            System.Windows.Application.LoadComponent(this, resourceLocater);
        }

        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [System.ComponentModel.EditorBrowsableAttribute
        (System.ComponentModel.EditorBrowsableState.Never)]
        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute
        ("Microsoft.Design", 
        "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
        void System.Windows.Markup.IComponentConnector.Connect
                (int connectionId, object target) 
        {
            switch (connectionId)
            {
            case 1:
            this.Stack = ((System.Windows.Controls.StackPanel)(target));
            return;
            case 2:
            this.lblColor = ((System.Windows.Controls.Label)(target));
            return;
            case 3:
            this.lstColorPicker = ((ColorPicker.ColorPickerControl)(target));
            return;
            }
            this._contentLoaded = true;
        }
    }
}

It can be seen that this source file provides the missing parts, most noticeably the InitializeComponent() method and also notice that there are a few instance fields which represent the components within the XAML file. So this is how both the code behind and XAML files are compiled to form a single assembly with all the required information.

Demo Of The Attached Application

The last thing I should show is the running app. That part is probably not so important, as it is the concepts I was trying to share really.

But for completeness sake, here is a screen shot.

remember the ColorPicker is simply a specialized ListBox really. Quite impressive no?

That's it

Well although we've only created a simple control and used it within a single XAML page, I hope you can see that there are quite a few core concepts that were covered here.

So What Do You Think ?

I would just like to ask, if you liked the article please vote for it, as it lets me know if the article was at the right level or not.

Conclusion

I have quite enjoyed constructing this article. I hope you liked it. I think it will help you a lot when you get time to do some XAML / WPF type apps. I have only just started out with XAML and I truly believe it is set to totally change the sort of applications we are all going to see.

History

  • v1.1 01/03/07: Fixed the custom event with custom event args issue. Thanks very much to Steve Maier.
  • v1.0 01/03/07: Initial Issue

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Sacha Barber
Software Developer (Senior)
United Kingdom United Kingdom
I currently hold the following qualifications (amongst others, I also studied Music Technology and Electronics, for my sins)
 
- MSc (Passed with distinctions), in Information Technology for E-Commerce
- BSc Hons (1st class) in Computer Science & Artificial Intelligence
 
Both of these at Sussex University UK.
 
Award(s)

I am lucky enough to have won a few awards for Zany Crazy code articles over the years

  • Microsoft C# MVP 2013
  • Codeproject MVP 2013
  • Microsoft C# MVP 2012
  • Codeproject MVP 2012
  • Microsoft C# MVP 2011
  • Codeproject MVP 2011
  • Microsoft C# MVP 2010
  • Codeproject MVP 2010
  • Microsoft C# MVP 2009
  • Codeproject MVP 2009
  • Microsoft C# MVP 2008
  • Codeproject MVP 2008
  • And numerous codeproject awards which you can see over at my blog

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralIt's really good staf!memberComponentsDev12-Aug-08 23:00 
I enjoy with this article. I'm new in WPF. Can someone tell me if the WPF technology is really popular? What do you think. The WPF controls will have good future?
 

GeneralRe: It's really good staf!mvpSacha Barber13-Aug-08 0:21 
Yeah WPF will catch on in a big way soon enough
 
Sacha Barber
  • Microsoft Visual C# MVP 2008
  • Codeproject MVP 2008
Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue
 
My Blog : sachabarber.net

GeneralRe: It's really good staf!memberman2tek7-Nov-09 17:43 
Yeah I think WPF will be the future . Thumbs Up | :thumbsup:
GeneralI want cloud to come up when i move mouse on a button -- in WPFmemberDinesh Patel25-Jul-08 2:35 
Can u plz help me out.... I have created an graph like application in WPF. I want to show comment(ToolTip) whenever i move mouse on a button(which is used to show point on line graph) and it should look like a cloud.. Plz help me out...
GeneralRe: I want cloud to come up when i move mouse on a button -- in WPFmvpSacha Barber25-Jul-08 2:50 
So you would do something like
 
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="UntitledProject1.Window1"
x:Name="Window"
Title="Window1"
Width="640" Height="480">
 

<Window.Resources>
 

<DrawingBrush x:Key="cloudBrush" Stretch="Uniform">
<DrawingBrush.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Brush="Yellow"
Geometry="F1 M 11.1667,17.1406C 22.1667,3.8073 10.8333,
-4.85938 22.1667,4.14062C 33.5,13.1406 30.5,11.8073
33.1667,12.474C 35.8333,13.1406 40.8333,20.8073
40.8333,20.8073L 38.1667,31.1406L 34.5,37.1406L
30.5,43.1406L 26.5,39.474L 18.1667,44.1406L
18.1667,37.474L 5.83333,39.474L 14.5,30.474L
0.5,28.1406L 14.8333,22.8073L 11.1667,17.1406 Z ">
<GeometryDrawing.Pen>
<Pen LineJoin="Round" Brush="Black"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingGroup.Children>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
 

<Style TargetType="{x:Type ToolTip}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToolTip}">
<Grid Name="Border" Background="{StaticResource cloudBrush}"
Width="300" Height="300">
<ContentPresenter Margin="10,0,10,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
TextBlock.Foreground="Black"
TextBlock.FontSize="12" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
 
</Window.Resources>


<Grid x:Name="LayoutRoot">
<Button x:Name="btn" Margin="20" ToolTip="I am a cloud tooltip"/>
</Grid>
</Window>
 
Obviously for the Geometry, you will need to create the points as you want them.
 
Sacha Barber
  • Microsoft Visual C# MVP 2008
  • Codeproject MVP 2008
Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue
 
My Blog : sachabarber.net

GeneralExpression Blend and Customer User ControlmemberBlitzPackage19-May-08 13:13 
Again, another great job. I envy your abilities. One day, I'll be just as good.
 
At any rate, I have a quick question regarding custom controls. I use Expression Blend (and Visual Studio C# 2008 for business logic) to do the following:
 
I have created a custom listbox (derived from usercontrol). I have added a main grid and designed a nice header (using a few borders to create a multicolor shine effect, a label with a nice font, and an icon) and footer (that has the borders for shine effect) that are located in rows at the top and bottom occupying about 1/5 of the entire grid height. I have placed a "ContentPresenter" in the middle row of the grid and that occupies the remaining space (approximately the remaining 3/5 of the grid height).
 
I have also created a custom listbox item. This listbox item has no content presenter. Instead, using a grid, I have created a border with a gradient fill for the back ground. Also, I have creatively arranged labels and an ellipse to make the custom listbox item look really good. The software I am working on is something entertaining for a client.
 
My question is as follows. How do I deploy the listbox in such a way that it uses my custom listbox template and custom listbox item to show the data? Also, I get (I think) that I must bind data to individual elements on the custom listbox item. However, I am not sure how to do this using expression blend. I am trying to bind it to a CLR object (i.e. my own Customer class which has the properties "Customer.Name", "Customer.VoicePhone", etc...). Should I build the business logic first & completely(i.e. in order to bind to all the objects), then use expression blend to put the front end on?
 
Any thoughts or directs would be greatly appreciated.
 
Thanks,
BP
GeneralRe: Expression Blend and Customer User ControlmvpSacha Barber19-May-08 20:09 
So there are a couplle of things here.
 
1. Using your own Listbox. You need to lookup xmlns:local="clr-namespace...." this is how you add a using type statement to a namespace in XAML. So then you will be able to do something like
 

 
2. To get the listbox to use your Style/Template, you need to make sure your Style or Template is in a Resource dictionary somewhere, say within the current Window.
 

 
<style x:key="mycustomListBoxStyle">
....
</style>
 

<!-- Or this could be a Template -->
 

 
So then you could do
 

 
So thats how you get it to use the Style/Template of your picking
 
3. To get the LitBox items to use your Template (which should be a DataTemplate to match the CLR objects in the listbox). You just need to set the ItemTemplate DP of the listbox, so something like
 

 
Where MyListItems is a DataTemplate within some resource dictionary, say Window.Resources.
 
4. So in the DataTemplate, the parts that you want to use properties from the underlying CLR object that is in the listbox item, just use Binding, something like
 

....
<label content="{Binding Path=SomtProperty}" />
 

 
Have a look at
 
http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemtemplate.aspx
 
This explains this principle.
 
Good luck
 
Sacha Barber
  • Microsoft Visual C# MVP 2008
  • Codeproject MVP 2008
Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue
 
My Blog : sachabarber.net

GeneralRe: Expression Blend and Customer User ControlmemberBlitzPackage19-May-08 22:38 
Thanks Sacha, I will look at that information. I thought that Expression Blend took care of all the namespace matters for you. I added a reference to the custom controls .dll that I created. While I could see the items in my .exe project, and even add them, they wouldn't show up when I tried to run it, or the main listbox would disappear when I tried to add content. Do I actually have to go into the code and do it myself? Also, I added my custom items control
 
Again, though, thanks for your answer. Just to know I can do it gives me strength to figure it out!
GeneralRe: Expression Blend and Customer User ControlmvpSacha Barber20-May-08 2:44 
To be honest I dont use Blend for all but the simlist tasks, so always hand code.
 
So cant answer Blend queries
 
Sacha Barber
  • Microsoft Visual C# MVP 2008
  • Codeproject MVP 2008
Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue
 
My Blog : sachabarber.net

QuestionWPF resources from dllmemberdmitrdv9-Apr-08 18:49 
Sacha, you wrote how to use custom control from dll
And how to use resources (styles and template) from dll?
 
in some dll:
1) MyCustomControl.cs with some custom control
2) resource1.xaml:
<style targettype="{Type" mycustomcontrol}="">
......
 
In wpf application i am use this library. I know how to use MyCustomControl.
But how to apply style from dll to custom control?
 
qwe
</style>
GeneralRe: WPF resources from dllmvpSacha Barber9-Apr-08 20:32 
Have a look at josh smiths, 3d Panel or skinning at runtime articles, he uses the Application.LoadComponent, which is what you need.
 
Sacha Barber
  • Microsoft Visual C# MVP 2008
  • Codeproject MVP 2008
Your best friend is you.
I'm my best friend too. We share the same view, and never argue
 
My Blog : sachabarber.net

Questionadd it to the toolbox?memberferdna24-Aug-07 7:34 
how do you add it to the toolbox?
 
( i tried but when dropping the document on my window1.xaml nothing happens... )
 
It Is Not That I'm Different!
... I'm Only Making The Difference!

AnswerRe: add it to the toolbox?memberSacha Barber24-Aug-07 21:35 
to be honest with you I didnt try adding it to the toolbox.
 
I cant see why it wouldnt work.
 
But if it isnt wowking out for you, I would stuill to code creation of a control.
 
Sacha Barber
A Modern Geek - I cook, I clean, I drink, I Program. Modern or what?
 
My Blog : sachabarber.net

GeneralGot your custom stuff working.memberSteve Maier1-Mar-07 7:57 
I like your article and worked abit and got your custom eventargs stuff working too. Here is how I did it:
 
First I uncommented your custom eventarg code in the ColorPickerControl.cs file.
 
Then I added this to the RaiseNewColorCustomerEvent method, right before the RaiseEvent call.
newEventArgs.RoutedEvent = ColorPickerControl.NewColorCustomEvent;
Then to the main app you can add this code to the constructor
lstColorPicker.NewColorCustom += new ColorPicker.ColorPickerControl.NewColorCustomEventHandler(lstColorPicker_NewColorCustom);
and the handler
private void lstColorPicker_NewColorCustom(object sender, ColorRoutedEventArgs e)
{
     MessageBox.Show(e.ColorName);
}
It should all work fine after that.
 
Steve Maier

GeneralRe: Got your custom stuff working.memberSacha Barber1-Mar-07 9:06 
All done just like you said.
 
Thanks very much for that. Its very strange that you have to tell a custom event arg which event it belong to just before you raise the event. BUt hey ho, there you go.
 
As I say thanks very much.
 
Zip and article are updated.
 
Smile | :) Smile | :) Smile | :) Smile | :)
 
sacha barber

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130617.1 | Last Updated 1 Mar 2007
Article Copyright 2007 by Sacha Barber
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid