Click here to Skip to main content
15,891,673 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Ok, here's the problem - and I'll do my best to actually explain it.

I have two methods pulling two different fields/values form the database: Type and Status. The methods are working and oulling the correct values for each. On the XAML page, I have three comboboxes. Example:

C#
<ComboBox x:Name="CbType" HorizontalAlignment="Right" Margin="0,10,18.2,0" VerticalAlignment="Top" Width="120" ItemsSource="{Binding}" />

<ComboBox x:Name="CbStatus" HorizontalAlignment="Left" Margin="89,91,0,77.4"
Width="120" ItemsSource="{Binding}" d:LayoutOverrides="Height" />


The problem is the ItemsSource="{Binding}". Binding, I think, should look something like ItemsSource="{Binding Type}" and ItemsSource="{Binding Statuses}". I can't figure out how to set this "names" to the binding. Without suppling a different value for each Binding, I get no values at all in the combobox. If I take out the second method and second ItemSource in the XAML, it works for only one of the comboboxes. I think the "code" doesn't know how to differeniate between the two, so how to do I help it understand? :)

Here is an example of the method:

C#
public void GetAddrTypes()
        {
            //***Set Variables***

            var preSql = Settings.Default.GetAddrTypes;
            var sql = preSql;

            Log.Debug("SP: " + preSql + " for GetAddrTypes()");
            Log.Debug("Dbconn called and created for GetAddrTypes()");

            var connectionString = Settings.Default.Dbconn;
            using (var conn = new SqlConnection(connectionString))
                //using (var cmd = new SqlCommand(sql, conn))
            {
                try
                {
                    conn.Open();
                    var adpter = new SqlDataAdapter(sql, conn);
                    var ds = new DataSet();
                    adpter.Fill(ds);
                    CbType.DataContext = ds.Tables[0];
                    CbType.DisplayMemberPath = "AddrTypeCode";
                    CbType.SelectedValuePath = "AddrTypeCode";
                    Log.Debug("Command executed and reader completed for GetAddrTypes()");
                }
                catch (SqlException ex)
                {
                    // Build custom message box for exception upload
                    var msg = ex.ToString();
                    var title = DataLogic.Properties.Resources.CustomMsgBxTitle;
                    MessageBoxManager.Ok = "Copy";
                    MessageBoxManager.Cancel = "Ignore";
                    MessageBoxManager.Register();
                    var result = MessageBox.Show(msg, title, MessageBoxButtons.OKCancel,
                        MessageBoxIcon.Hand);
                    switch (result)
                    {
                        case System.Windows.Forms.DialogResult.OK:
                            Clipboard.SetText(msg);
                            break;
                        case System.Windows.Forms.DialogResult.Cancel:
                            break;
                    }
                    MessageBoxManager.Unregister();
                    Log.Error("Exception Thrown: " + msg + " - for while calling GetAddrTypes");
                }
                finally
                {
                    Log.Info("Closing SQL Connection for GetAddrTypes()");
                }
            }
        }


Here is the Page Load

C#
private void MetroWindow_Loaded(object sender, RoutedEventArgs e)
       {
           TbId.Text = Idval;
           CbType.SelectedValue = Typeval;
           TbDesc.Text = Descval;
           CbStatus.SelectedValue = Statval;
           CbSysReq.SelectedValue = Sysreqval;
           GetAddrTypes();
           GetStatusCodes();
       }


What I have tried:

public ObservableCollection<> "name" { get; set; }
But these are classes I'm calling.
Posted
Updated 23-May-16 18:59pm
Comments
[no name] 24-May-16 0:49am    
Are you using mvvm ?

1 solution

Hi,

The basic of binding this would be using a list to create the data in view model. I will try to explain it here.

1.) Create a sample class :
C#
public class ComboData : INotifyPropertyChanged
    {
        private string _text { get; set; }
        private string _values { get; set; }

        public string Text
        {
            get { return _text; }
            set
            {
                _text = value;
                OnPropertyChanged("Text");
            }
        }

        public string Values
        {
            get { return _values; }
            set
            {
                _values = value;
                OnPropertyChanged("Value");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }


2.) In your class add the properties for two lists:
C#
List<ComboData> _typeList = new List<ComboData>();

       public List<ComboData> TypeList
       {
           get { return _typeList; }
           set
           {
               _typeList = value;
               RaisePropertyChanged(() => TypeList);
           }
       }

       List<ComboData> _statusList = new List<ComboData>();

       public List<ComboData> StatusList
       {
           get { return _statusList; }
           set
           {
               _statusList = value;
               RaisePropertyChanged(() => StatusList);
           }
       }


These two properties are in my view model. If you are wondering what is RaisePropertyChanged() here, it is the implementation for my ViewModelBase.

My sample ViewModelBase can be like:
C#
public abstract class ViewModelBase : INotifyPropertyChanged
    {
        protected void RaisePropertyChanged<T>(Expression<Func<T>> action)
        {
            var propertyName = GetPropertyName(action);
            RaisePropertyChanged(propertyName);
        }

        private static string GetPropertyName<T>(Expression<Func<T>> action)
        {
            var expression = (MemberExpression)action.Body;
            var propertyName = expression.Member.Name;
            return propertyName;
        }

        public void RaisePropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;        
    }


3.) Create a sample data in your view model constructor. If you are not using mvvm approach, create this in your Loaded event:
C#
TypeList.Add(new ComboData {Text = "1234", Values = "1234"});
TypeList.Add(new ComboData {Text = "1234", Values = "41234"});

StatusList.Add(new ComboData {Text = "agfasd", Values = "asgas"});
StatusList.Add(new ComboData {Text = "ag", Values = "asdg"});

So basically, here we have a text property that will be for display binded with a value for its value member path.

4.) Add the ComboBox in your xaml:
XML
<combobox grid.row="1" grid.column="1" x:name="CbType" itemssource="{Binding TypeList}" displaymemberpath="Text" selectedvaluepath=" Values" xmlns:x="#unknown" />


This should work.

Try searching on google and see what are basics of binding a combobox.

Hope this helps !
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900