Solved

How to populate a custom user control drop down based upon another custom user control drop down selection?

Posted on 2011-03-14
5
396 Views
Last Modified: 2012-08-13
I have two custom user controls, one called Plant and one called Line. They are drop down lists. When a user selects a plant from the Plant drop down, I want the Line custom control to only populate with the lines associated with the selected plant. How would I go about doing this?

I am using WPF controls.

Here is the code for the Plant and Line custom controls.

<UserControl x:Class="HCB.UI.ABISS3.WindowsAndControls.UserControls.Plants"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d" MinHeight="23" MaxHeight="23" Height="23" Width="208">
    <Grid>
        <ComboBox Name="cboItems" />
    </Grid>
</UserControl>


<UserControl x:Class="HCB.UI.ABISS3.WindowsAndControls.UserControls.Lines"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d" MinHeight="23" MaxHeight="23" Height="23" Width="208">
    <Grid>
        <ComboBox Name="cboItems" />
    </Grid>
</UserControl>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using HCB.Layers.DataTransferObjects.Locations;


namespace HCB.UI.ABISS3.WindowsAndControls.UserControls
{
    /// <summary>
    /// Interaction logic for Plants.xaml
    /// </summary>
    public partial class Plants : UserControl
    {          
        #region Fields and Properties

        private ObservableCollection<HCB.Layers.DataTransferObjects.Locations.Location> _plants;

        private bool _includeAllRecord = false;

        /// <summary>
        /// Include the All record into the list
        /// </summary>
        public bool IncludeAllRecord
        {
            get
            {
                return _includeAllRecord;
            }
            set
            {
                _includeAllRecord = value;
                InsertAllRecord();
            }
        }

        /// <summary>
        /// Select the All record
        /// </summary>
        public bool SelectAllRecord
        {
            set
            {
                if (_includeAllRecord)
                    cboItems.SelectedIndex = 0;
            }
        }

        /// <summary>
        /// Selection changed event
        /// </summary>
        public event SelectionChangedEventHandler SelectionChanged
        {
            add
            {
                cboItems.SelectionChanged += value;
            }
            remove
            {
                cboItems.SelectionChanged -= value;
            }
        }

        /// <summary>
        /// Get or set the selected item
        /// </summary>
        public HCB.Layers.DataTransferObjects.Locations.Location SelectedItem
        {
            get
            {
                return (HCB.Layers.DataTransferObjects.Locations.Location)cboItems.SelectedItem;
            }

            set
            {
                cboItems.SelectedItem = value;
            }
        }

        /// <summary>
        /// Get or set the selected index
        /// </summary>
        public int SelectedIndex
        {
            get
            {
                return cboItems.SelectedIndex;
            }

            set
            {
                cboItems.SelectedIndex = value;
            }
        }

        #endregion

        #region Ctor

        /// <summary>
        /// Instance constructor
        /// </summary>
        public Plants()
        {
            InitializeComponent();
        }

        #endregion

        #region Protected Methods

        /// <summary>
        /// OnInitialized
        /// </summary>
        /// <param name="e"></param>
        protected override void OnInitialized(EventArgs e)
        {
            base.OnInitialized(e);
            InitCombo();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Insert the All record
        /// </summary>
        private void InsertAllRecord()
        {
            if (_plants != null)
            {
                if (_includeAllRecord)
                    _plants.Insert(0, HCB.Layers.DataTransferObjects.Locations.Location.GetComboAllPlant());
            }
        }

        /// <summary>
        /// Init the combo box
        /// </summary>
        private void InitCombo()
        {
            try
            {
                if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
                {
                    using (LocationClient client = new LocationClient())
                    //using (LocationClient client = new LocationClient())
                    {
                        _plants = new ObservableCollection<HCB.Layers.DataTransferObjects.Locations.Location>(client.Plants_GetAllActive());

                        InsertAllRecord();

                        cboItems.ItemsSource = _plants;

                        cboItems.DisplayMemberPath = HCB.Layers.DataTransferObjects.Locations.Location.PropertyNames.LocationWarehouseName;
                        cboItems.SelectedValuePath = HCB.Layers.DataTransferObjects.Locations.Location.PropertyNames.LocationID;
                    }
                }
            }
            catch (Exception ex)
            {
                //TODO: Add Logging
                string logMsg = ex.Message;
                MessageBox.Show(string.Format("Unable to Load the plant list. {0}", HCB.Layers.Common.Constants.Messages.ErrorAction), HCB.Layers.Common.Constants.WindowTitles.Application, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        #endregion
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using HCB.Layers.DataTransferObjects.Locations;


namespace HCB.UI.ABISS3.WindowsAndControls.UserControls
{
    /// <summary>
    /// Interaction logic for Plants.xaml
    /// </summary>
    public partial class Lines : UserControl
    {
        #region Fields and Properties

        private ObservableCollection<HCB.Layers.DataTransferObjects.Locations.Line> _lines;

        private bool _includeAllRecord = false;

        /// <summary>
        /// Include the All record into the list
        /// </summary>
        public bool IncludeAllRecord
        {
            get
            {
                return _includeAllRecord;
            }
            set
            {
                _includeAllRecord = value;
                InsertAllRecord();
            }
        }

        /// <summary>
        /// Select the All record
        /// </summary>
        public bool SelectAllRecord
        {
            set
            {
                if (_includeAllRecord)
                    cboItems.SelectedIndex = 0;
            }
        }

        /// <summary>
        /// Selection changed event
        /// </summary>
        public event SelectionChangedEventHandler SelectionChanged
        {
            add
            {
                cboItems.SelectionChanged += value;
            }
            remove
            {
                cboItems.SelectionChanged -= value;
            }
        }

        /// <summary>
        /// Get or set the selected item
        /// </summary>
        public HCB.Layers.DataTransferObjects.Locations.Line SelectedItem
        {
            get
            {
                return (HCB.Layers.DataTransferObjects.Locations.Line)cboItems.SelectedItem;
            }

            set
            {
                cboItems.SelectedItem = value;
            }
        }

        /// <summary>
        /// Get or set the selected index
        /// </summary>
        public int SelectedIndex
        {
            get
            {
                return cboItems.SelectedIndex;
            }

            set
            {
                cboItems.SelectedIndex = value;
            }
        }

        #endregion

        #region Ctor

        /// <summary>
        /// Instance constructor
        /// </summary>
        public Lines()
        {
            InitializeComponent();
        }

        #endregion

        #region Protected Methods

        /// <summary>
        /// OnInitialized
        /// </summary>
        /// <param name="e"></param>
        protected override void OnInitialized(EventArgs e)
        {
            base.OnInitialized(e);
            InitCombo();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Insert the All record
        /// </summary>
        private void InsertAllRecord()
        {
            if (_lines != null)
            {
                if (_includeAllRecord)
                    _lines.Insert(0, HCB.Layers.DataTransferObjects.Locations.Line.GetComboLineByPlant());
            }
        }

        /// <summary>
        /// Init the combo box
        /// </summary>
        private void InitCombo()
        {
            try
            {
                if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
                {
                    using (LocationClient client = new LocationClient())
                    //using (LocationClient client = new LocationClient())
                    {
                        _lines = new ObservableCollection<HCB.Layers.DataTransferObjects.Locations.Line>(client.Lines_GetByPlant());

                        InsertAllRecord();

                        cboItems.ItemsSource = _lines;

                        cboItems.DisplayMemberPath = HCB.Layers.DataTransferObjects.Locations.Line.PropertyNames.LocationLine;
                        cboItems.SelectedValuePath = HCB.Layers.DataTransferObjects.Locations.Line.PropertyNames.LocationLine;
                    }
                }
            }
            catch (Exception ex)
            {
                //TODO: Add Logging
                string logMsg = ex.Message;
                MessageBox.Show(string.Format("Unable to Load the line list. {0}", HCB.Layers.Common.Constants.Messages.ErrorAction), HCB.Layers.Common.Constants.WindowTitles.Application, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        #endregion
    }
}
0
Comment
Question by:jjliu4492
  • 3
  • 2
5 Comments
 
LVL 10

Expert Comment

by:Nash2334
ID: 35129932
If they are in separate user controls there are a couple of different ways for them to communicate:

1. An event handler that is wired from one to the other.  For example, you raise an event on the SelectedIndexChanged for the Plants user control that the Lines user control listens to.  Since the value of the Plants impacts the Lines, you will likely need a custom delegate with custom event arguments to achieve this.

2. Expose a property in the Lines combobox and have the SelectedIndexChanged event of the Plants combobox set it.  In the setter method, filter the combobox accordingly.

Are you sure they need to be in separate user controls?
0
 

Author Comment

by:jjliu4492
ID: 35130882
Yes they need to be in separate user controls. Can you give me some example code on how to do this?
0
 
LVL 10

Accepted Solution

by:
Nash2334 earned 500 total points
ID: 35131220
Following is a detailed example.  UC1 filters UC2 - the ASPX acts as an intermediary, wiring to the event in UC1 and setting the property in UC2.

DEFAULT.ASPX
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ASP.NETCSharpSandbox.Default" %>

<%@ Register src="Controls/WebUserControl1.ascx" tagname="WebUserControl1" tagprefix="uc1" %>
<%@ Register src="Controls/WebUserControl2.ascx" tagname="WebUserControl2" tagprefix="uc2" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>    
        <uc1:WebUserControl1 ID="WebUserControl11" runat="server" />    
        <uc2:WebUserControl2 ID="WebUserControl21" runat="server" />
    </div>
    </form>
</body>
</html>

DEFAULT.ASPX.CS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace ASP.NETCSharpSandbox
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }

        protected void Page_PreInit(object sender, EventArgs e)
        {
            WebUserControl11.OnFilterSelected += new NETCSharpSandbox.Controls.WebUserControl1.OnFilterSelectedEvent(WebUserControl11_OnFilterSelected);
        }

        private void WebUserControl11_OnFilterSelected(object sender, Controls.OnFilterSelectedEventArgs e)
        {
            // Set property of second user control
            WebUserControl21.Filter = e.Filter;
        }
    }
}

WEBUSERCONTROL1.ASCX
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="WebUserControl1.ascx.cs" Inherits="ASP.NETCSharpSandbox.Controls.WebUserControl1" %>
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True"
    onselectedindexchanged="DropDownList1_SelectedIndexChanged">
</asp:DropDownList>

WEBUSERCONTROL1.ASCX.CS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;

namespace ASP.NETCSharpSandbox.Controls
{
    public partial class WebUserControl1 : System.Web.UI.UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                BindDropDownList();
            }
        }

        private void BindDropDownList()
        {
            System.Collections.ArrayList states = new System.Collections.ArrayList();
            states.Add("Illinois");
            states.Add("California");
            states.Add("New York");

            DataTable dt = new DataTable();
            dt.Columns.Add(new DataColumn("State"));

            dt.BeginLoadData();
            DataRow blank = dt.NewRow();
            blank.BeginEdit();
            blank[0] = string.Empty;
            blank.EndEdit();
            dt.Rows.Add(blank);

            foreach (string s in states)
            {
                DataRow r = dt.NewRow();
                r.BeginEdit();
                r[0] = s;
                r.EndEdit();
                dt.Rows.Add(r);
            }

            dt.EndLoadData();
            DropDownList1.DataTextField = "State";
            DropDownList1.DataValueField = "State";
            DropDownList1.DataSource = dt.DefaultView;
            DropDownList1.DataBind();
        }

        protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (DropDownList1.SelectedValue != null)
            {
                if (OnFilterSelected != null)
                    OnFilterSelected(this, new OnFilterSelectedEventArgs(DropDownList1.SelectedValue));
            }
        }

        public delegate void OnFilterSelectedEvent(object sender, OnFilterSelectedEventArgs e);
        public event OnFilterSelectedEvent OnFilterSelected;
    }

    public class OnFilterSelectedEventArgs : EventArgs
    {
        private string _filter;
        public string Filter
        {
            get { return _filter; }
        }

        public OnFilterSelectedEventArgs(string filter)
        {
            _filter = filter;
        }
    }
}

WEBUSERCONTROL2.ASCX
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="WebUserControl2.ascx.cs" Inherits="ASP.NETCSharpSandbox.Controls.WebUserControl2" %>
<asp:DropDownList ID="DropDownList2" runat="server">
</asp:DropDownList>

WEBUSERCONTROL2.ASCX.CS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;

namespace ASP.NETCSharpSandbox.Controls
{
    public partial class WebUserControl2 : System.Web.UI.UserControl
    {
        private string _filter = string.Empty;
        public string Filter
        {
            get { return _filter; }
            set
            {
                if (value != null)
                {
                    BindDropDownList(value);
                }
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                BindDropDownList(null);
            }
        }

        private void BindDropDownList(string filter)
        {
            System.Collections.ArrayList cities = new System.Collections.ArrayList();
            cities.Add("Chicago");
            cities.Add("Los Angeles");
            cities.Add("New York");

            DataTable dt = new DataTable();
            dt.Columns.Add(new DataColumn("City"));

            foreach (string s in cities)
            {
                dt.BeginLoadData();
                DataRow r = dt.NewRow();
                r.BeginEdit();
                r[0] = s;
                r.EndEdit();
                dt.Rows.Add(r);
            }

            dt.EndLoadData();

            DropDownList2.DataTextField = "City";
            DropDownList2.DataValueField = "City";

            if (filter != null)
            {
                string f = string.Empty;

                if (filter.Equals("Illinois"))
                    f = "City = 'Chicago'";
                else if (filter.Equals("California"))
                    f = "City = 'Los Angeles'";
                else if (filter.Equals("New York"))
                    f = "City = 'New York'";

                if (!f.Equals(string.Empty))
                    dt.DefaultView.RowFilter = f;
            }
           
            DropDownList2.DataSource = dt.DefaultView;
            DropDownList2.DataBind();
        }
    }
}

Good luck.
0
 

Author Comment

by:jjliu4492
ID: 35131489
My user controls are WPF controls, so I can not use OnFilterSelectedEventArgs. What would be the code for my user controls, since they are WPF controls?
0
 
LVL 10

Expert Comment

by:Nash2334
ID: 35131655
OnFilterSelectedEventArgs is a custom class that is not specific to ASP.NET.  The principles here for WPF are similar, except the MainWindow would be the intermediary instead of a Default.aspx page.  You would define the event in your first WPF user control, wire to an event and set a property on the second.
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now