Search code examples
c#wpfcomboboxbinding

Basic ComboBoxItem Binding Programmatically In C# WPF


I am trying to change ComboBoxItem Template Programmatically

//Main Style
Style style = new Style() { TargetType = typeof(ComboBoxItem) };
//Set Template
ControlTemplate temp = new ControlTemplate(typeof(ComboBoxItem));
style.Setters.Add(new Setter() { Property = Control.TemplateProperty, Value = temp });

//Item Border
FrameworkElementFactory itemB = new FrameworkElementFactory(typeof(Border));
itemB.SetValue(Border.BorderBrushProperty, Brushes.Red);
itemB.SetValue(Border.WidthProperty, (double)500);
itemB.SetValue(Border.HeightProperty, (double)30);
itemB.SetValue(Border.BorderThicknessProperty, new Thickness(2));
itemB.SetValue(Border.BackgroundProperty, Brushes.GreenYellow);
temp.VisualTree = itemB;

//Item Label
FrameworkElementFactory itemT = new FrameworkElementFactory(typeof(Label));
itemT.AppendChild(itemB);
itemT.SetValue(Label.ForegroundProperty, Brushes.Red);

/* This Part Is Not Working*/
itemT.SetBinding(Label.ContentProperty, new Binding { RelativeSource = RelativeSource.Self });
        
//Set Template
Application.Current.Resources[typeof(ComboBoxItem)] = style;

I Also Tried This

itemT.SetBinding(Label.ContentProperty, new Binding { Source = ComboBoxItem.ContentProperty });

The problem is that items name are not getting shown in dropdown list.

This is how i am adding comboBox

//ComboBox
ComboBox combobox = new ComboBox() {Height = 30, Width = 500};
combobox.Items.Add("OK 1");
combobox.Items.Add("OK 2");
combobox.Items.Add("OK 3");
combobox.Items.Add("OK 4");

Here is how my dropdown looks

enter image description here


Solution

  • Besides that it is unclear why you won't simply do this in XAML, both

    itemT.SetBinding(Label.ContentProperty,
       new Binding { RelativeSource = RelativeSource.Self });
    

    and

    itemT.SetBinding(Label.ContentProperty,
        new Binding { Source = ComboBoxItem.ContentProperty });
    

    are wrong for two reasons. They are missing a property Path and use the wrong binding source object.

    In a ControlTemplate you would bind to the Content property of the templated parent element:

    itemT.SetBinding(Label.ContentProperty,
        new Binding
        {
            Path = new PropertyPath(ComboBoxItem.ContentProperty),
            // or Path = new PropertyPath(nameof(ComboBoxItem.Content)),
            RelativeSource = RelativeSource.TemplatedParent
        });
    

    You may also use a TemplateBinding by

    itemT.SetValue(Label.ContentProperty,
        new TemplateBindingExtension(ComboBoxItem.ContentProperty));
    

    There should also be

    itemB.AppendChild(itemT);
    

    instead of

    itemT.AppendChild(itemB);