CameTooFar

A Nerd's False Positive.

Silverlight Error - The type or namespace name 'Label' does not exist in the namespace 'System.Windows.Controls' (are you missing an assembly reference?)


Recently, I’s adding an existing Silverlight Project to a newly created Silverlight project. Of course, the xaml contains controls in its Design, including Label control.

Soon after adding the xaml’s, I hit F5, boom! – Compiler time error:

“The type or namespace name 'Label' does not exist in the namespace 'System.Windows.Controls' (are you missing an assembly reference?)”

What? My new Silverlight project doesn’t have a Label control?

Well, my newly created project was missing an assembly reference & can fix it by adding a reference of the assembly:

System.Windows.Controls.Data.Input.dll

Yup! It’s fixed.

Why you should learn Delegates?


What everyone should learn while start writing code is the Basic Fundamentals, which most of them doesn’t do (myself among the one). Instead they go behind the attractive features, which is easy to learn and understand. In short run, you’ll win. But, in the long run, you’ll fail or you’ll end up using more lines of codes than required or you’ll write the most ugliest code.

I’m no different and I end up writing bloody-ugly code, due to my ignorance, delay and laziness to learn the fundamentals.

Few months back, I’m playing with user-controls in Silverlight 4, in which I want to pass data from one user control to another. And, delegate is the most perfect and standard way to do that.

The Ugly side of Ignorance – Object Passing

My situation was like this, I have a main page (say, MainPage.xaml) in which I’m loading a User Control (say, DocumentDetails.xaml). The MainPage.xaml contains a Label control which displays the total number of documents loaded in the  DocumentDetails.xaml.

Something like this:

WithoutDelegate

What I’d done is, in my DocumentDetails.xaml, I created a property named DocumentCount whose type is Label. The purpose of this property is to keep a reference of the Label in the MainPage.xaml, so that any update to the property: DocumentCount will update the original Label content in the MainPage.xaml.

Here goes my (ugly) code:

Documents.cs (Custom Class)

/*** Documents.cs ***/
 
public class Documents
    {
        public int Id { get; set; }
 
        public string Name { get; set; }
 
        public string Type { get; set; }
    }

 

DocumentDetails.xaml (Design)

<!-- DocumentDetails.xaml (Design) -->
<Grid x:Name="LayoutRoot" Margin="10" Height="Auto" Width="Auto" 
HorizontalAlignment="Center" Background="White">
        <sdk:DataGrid AutoGenerateColumns="False" 
                      Height="Auto" 
                      Margin="10"
                      RowHeight="40"
                      HorizontalAlignment="Left" 
                      Name="dgDocuments" 
                      VerticalAlignment="Top" 
                      Width="Auto">
            <sdk:DataGrid.Columns>
                <sdk:DataGridTemplateColumn Header="Id" Width="50">
                    <sdk:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Id}" />
                        </DataTemplate>
                    </sdk:DataGridTemplateColumn.CellTemplate>
                </sdk:DataGridTemplateColumn>
                <sdk:DataGridTemplateColumn Header="Name" Width="150">
                    <sdk:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}" />
                        </DataTemplate>
                    </sdk:DataGridTemplateColumn.CellTemplate>
                </sdk:DataGridTemplateColumn>
                <sdk:DataGridTemplateColumn Header="Type" Width="150">
                    <sdk:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Type}" />
                        </DataTemplate>
                    </sdk:DataGridTemplateColumn.CellTemplate>
                </sdk:DataGridTemplateColumn>
            </sdk:DataGrid.Columns>
        </sdk:DataGrid>
    </Grid>

 

DocumentDetails.xaml.cs (Code-Behind)

/*** DocumentDetails.xaml.cs ***/
public partial class DocumentDetails : UserControl
    {
        /// <summary>
        /// Reference of Label object from MainPage.xml
        /// </summary>
        public Label DocumentCount { get; set; }
 
        /// <summary>
        /// Constructor
        /// </summary>
        public DocumentDetails()
        {
            InitializeComponent();
        }
 
        /// <summary>
        /// User Control Loaded
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            List<Documents> olstDocs = new List<Documents>() { 
                new Documents(){ Id = 1, Name = "Name 1", Type = "Type 1" },
                new Documents(){ Id = 2, Name = "Name 2", Type = "Type 2" },
                new Documents(){ Id = 3, Name = "Name 3", Type = "Type 3" },
                new Documents(){ Id = 4, Name = "Name 4", Type = "Type 4" },
                new Documents(){ Id = 5, Name = "Name 5", Type = "Type 5" }
            };
 
            // Set Count
            DocumentCount.Content = "Total Docs: " + olstDocs.Count;
 
            // Bind Data
            dgDocuments.ItemsSource = olstDocs;
        }
    }


MainPage.xaml (Design)

<!-- MainPage.xaml (Designer) -->
<Grid x:Name="LayoutRoot" Background="White" HorizontalAlignment="Center">
        <Grid.RowDefinitions>
            <RowDefinition Height="40" />
            <RowDefinition Height="40" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        
        <!-- Count -->
        <sdk:Label Grid.Row="0" 
                   Grid.Column="0" 
                   Name="lblCount" 
                   Content="Total Docs: " 
                   VerticalAlignment="Center" 
                   HorizontalAlignment="Left" 
                   VerticalContentAlignment="Center" 
                   Width="120" 
                   FontSize="12" />
 
        <!-- Load UserControl -->
        <Button Content="Load Documents" 
                Grid.Row="1" 
                Grid.Column="0"
                Height="23" 
                HorizontalAlignment="Left" 
                Name="btnLoadDocs" 
                VerticalAlignment="Center" 
                Click="btnLoadDocs_Click"
                Width="150" />
 
        <!-- Container -->
        <StackPanel Grid.Row="2" 
                    Grid.Column="0" 
                    x:Name="stkpnlContainer" 
                    Height="Auto" 
                    Width="400" 
                    HorizontalAlignment="Left" 
                    Orientation="Vertical" 
                    Background="Gray">
        </StackPanel>
        
    </Grid>

 

MainPage.xaml.cs (Code-Behind)

/*** MainPage.xaml.cs (Code-Behind) ***/
public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }
 
        /// <summary>
        /// Load Document Control
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnLoadDocs_Click(object sender, RoutedEventArgs e)
        {
            DocumentDetails oDocDetails = new DocumentDetails();
            // Pass the Label reference
            oDocDetails.DocumentCount = lblCount;
 
            stkpnlContainer.Children.Clear();
            stkpnlContainer.Children.Add(oDocDetails);
        }
    }

 

So what’s the problem with this? It’ll work fine. Correct?

Well the problem is, I’m passing the object reference itself. And the situation is more worse, if I want to update more Controls in my parent form (here MainPage.xaml), which makes me to pass more control reference, in turn making it ugly.

The Powerful side of Fundamentals – Delegates

Well…Well…Well… There is a powerful solution to handle this called Delegates. Simply, Delegate is function pointer, the most common definition that you’ll hear, if you ask a good amount of developers! Another definition? They’ll scratch their head.

Windows and Web development relies on event-driven mechanism. When you perform an Action (Event, say Click), you need a Method/Procedure (Event Handler) to be invoked as part of the action, to perform an operation. And, Delegate acts as a conduit between Event Source and Event Handler methods. The delegate carries the information about the Event to the Event Handler.

In our situation, you can handle the total count displaying in the MainPage.xaml by;

  1. Declaring delegate & event in the DocumentsDisplay.xaml
  2. Registering event in the MainPage.xaml & defining the event-handler method to handle the raised event
  3. Here goes the code:
    DocumentDetails.xaml.cs
    /*** DocumentDetails.xaml.cs ***/
    public partial class DocumentDetails : UserControl
        {
            /// <summary>
            /// Delegate
            /// </summary>
            /// <param name="count"></param>
            public delegate void TotalCountHandler(int count);
     
            /// <summary>
            /// Event to fire the "Total Count" value
            /// </summary>
            public event TotalCountHandler Count;
     
            /// <summary>
            /// Constructor
            /// </summary>
            public DocumentDetails()
            {
                InitializeComponent();
            }
     
            /// <summary>
            /// User Control Loaded
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void UserControl_Loaded(object sender, RoutedEventArgs e)
            {
                List<Documents> olstDocs = new List<Documents>() { 
                    new Documents(){ Id = 1, Name = "Name 1", Type = "Type 1" },
                    new Documents(){ Id = 2, Name = "Name 2", Type = "Type 2" },
                    new Documents(){ Id = 3, Name = "Name 3", Type = "Type 3" },
                    new Documents(){ Id = 4, Name = "Name 4", Type = "Type 4" },
                    new Documents(){ Id = 5, Name = "Name 5", Type = "Type 5" }
                };
     
                // Set Count
     
                // Check whether event is registered or not
                if (Count != null)
                {
                    // Fire Event
                    Count(olstDocs.Count);
                }
     
                // Bind Data
                dgDocuments.ItemsSource = olstDocs;
            }
        }
    MainPage.xaml.cs
    /*** MainPage.xaml.cs ***/
    public partial class MainPage : UserControl
        {
            DocumentDetails oDocDetails;
     
            /// <summary>
            /// Constructor
            /// </summary>
            public MainPage()
            {
                InitializeComponent();
            }
     
            /// <summary>
            /// Load Document Control
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnLoadDocs_Click(object sender, RoutedEventArgs e)
            {
                oDocDetails = new DocumentDetails();
                
                // Register Event
                oDocDetails.Count += new DocumentDetails.TotalCountHandler(oDocDetails_Count);
     
                stkpnlContainer.Children.Clear();
                stkpnlContainer.Children.Add(oDocDetails);
            }
     
            /// <summary>
            /// EventHandler method that sets the Total Count
            /// </summary>
            /// <param name="count"></param>
            void oDocDetails_Count(int count)
            {
                lblCount.Content = "Total Docs: " + count;
     
                // Remove Event
                oDocDetails.Count -= oDocDetails_Count;
            }
        }

Preview

Delegate

Download Source

Hope this helped. Thanks!

WPF vs WinForm Controls comparison chart


Windows Forms was introduced in Microsoft.NET platform as part of replacement of complex C++ based MFC (Microsoft Foundation Class) Library. Now its time to listen to Voices of WPF, an advanced graphical subsystem for rendering UI in windows-based application.

wpf logo

Win Form is a matured technology and WPF is an emerging technology.  When migrating from Win Form development to WPF development, what everyone, at least late adopters like me, needs a comparison char that lists out the control in WPF’s Toolbox when compared to the Win Form's Toolbox.

Thought late, I finally got an updated comparison char from MSDN. You can access it here.