Please don't judge me for my code. I'm new here :)
I had the same Problem today. I found a simple Solution for the problem. I hope it helps someone in the future.
My Workaround is to get the TextBox out of the Editable ComboBox and set the Binding via C# Code on the TextProperty of the extractet TextBox.
You have to add a Loaded Event in the XAML Code of the ComboBox:
<ComboBox x:Name="coboMyTestBox"
IsEditable="True"
Loaded="coboMyTestBox_Loaded"/>
This doesnt work with the Initialized Event, because the editable TextBox is not initialized at this moment. You need the Loaded Event!
Now extract the TextBox in your xaml.cs like that (the myDataPreset is my MVVM Object where i store the Data -> Example is further down)
private void coboMyTestBox_Loaded(object sender, EventArgs e)
{
//Extract the TextBox
var textBox = VisualTreeHelperExtensions.GetVisualChild<TextBox>((ComboBox)sender);
//Check if TextBox is found and if MVVM Object is Initialized
if (textBox != null && myDataPreset != null)
{
Binding binding = new Binding("MyStringVariable");
binding.Mode = BindingMode.TwoWay;
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(textBox, TextBox.TextProperty, binding);
}
}
Here is my class and function to extract the TextBox:
public static class VisualTreeHelperExtensions
{
public static T? GetVisualChild<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj == null) return null;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
var result = (child as T) ?? GetVisualChild<T>(child);
if (result != null) return result;
}
return null;
}
}
And here an example of my MVVM:
public class _MyDataPreset : INotifyPropertyChanged
{
//Private Definition
private string myStringVariable= "";
//Public Accessor - this is what the Binding calls
public string MyStringVariable
{
get { return myStringVariable; }
set
{
//You can modify the value here like filtering symbols with regex etc.
myStringVariable= value;
OnPropertyChanged(nameof(MyStringVariable));
}
//PropertyChanged Event Hanlder
public event PropertyChangedEventHandler? PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
I always initialize my MVVM Preset after the InitializeComponent() Event at the beginning like this or later if i need it at another point where i have to choose between multiple Templates:
public partial class MyUserControl : UserControl
{
private _MyDataPreset? myDataPreset;
public MyUserControl()
{
InitializeComponent();
myDataPreset = new _MyDataPreset();
}
//Here comes the coboMyTestBox_Loaded Event
}
Note:
The Extract Function also works great with Objects like the DatePicker to access the TextBox in the background.