C
C#2y ago
twiner

Sanity check on WPF CustomControl Binding to ViewModel not working

Can someone sanity check me here... In WPF I have a custom control derived from RichTextBox. I needed to have a way to access the selected text from my ViewModel so I could use it to inject into a new object created by said VM However, the value doesn't seem to move across the binding into the view model. So on my view model I made a SelectedText Property
public class MyViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler? PropertyChanged;
private string _selectedText;
public string SelectedText {
get => _selectedText;
set { _selectedText = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedText))); }
}
}
public class MyViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler? PropertyChanged;
private string _selectedText;
public string SelectedText {
get => _selectedText;
set { _selectedText = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedText))); }
}
}
and in my custom RichTextBox I have a DependencyProperty
public class AlertTextBox: RichTextBox {
public static readonly DependencyProperty SelectedTextProperty = DependencyProperty.Register(nameof(SelectedText), typeof(string), typeof(AlertTextBox));
public string SelectedText
{
get => (string)GetValue(SelectedTextProperty);
set => SetValue(SelectedTextProperty, value);
}
public AlertTextBox(){
Selection.Changed += SelectionChanged;
}
public void SelectionChanged(object sender, EventArgs e) => SetCurrentValue(SelectedTextProperty, Selection.Text);
}
public class AlertTextBox: RichTextBox {
public static readonly DependencyProperty SelectedTextProperty = DependencyProperty.Register(nameof(SelectedText), typeof(string), typeof(AlertTextBox));
public string SelectedText
{
get => (string)GetValue(SelectedTextProperty);
set => SetValue(SelectedTextProperty, value);
}
public AlertTextBox(){
Selection.Changed += SelectionChanged;
}
public void SelectionChanged(object sender, EventArgs e) => SetCurrentValue(SelectedTextProperty, Selection.Text);
}
Finally, in my test Window I have it bound together
<AlertTextBox SelectedText="{Binding Path=SelectedText}" />
<AlertTextBox SelectedText="{Binding Path=SelectedText}" />
When inspecting the UI with Snoop, I can see that the binding on SelectedText is considered valid. I believe that using SetCurrentValue is correct to allow the value to propagate across the binding to the ViewModel So I must be missing something, I've done this what feels like countless times and I just don't see what I'm overlooking
6 Replies
twiner
twiner2y ago
I have verified that the SelectionChanged callback is executed and that the value of Selection.Text is the expected value (the text that appears to be visually selected in the UI) I also tried changing the binding on Selected text to update on property change.
<AlertTextBox SelectedText="{Binding Path=SelectedText, UpdateSourceTrigger=PropertyChanged}" />
<AlertTextBox SelectedText="{Binding Path=SelectedText, UpdateSourceTrigger=PropertyChanged}" />
Alexicon
Alexicon2y ago
I think you need mode=twoway off the top of my head
twiner
twiner2y ago
😐 well that was it I've barely started my day and I feel like I should end it
Alexicon
Alexicon2y ago
haha, glad I remembered right
twiner
twiner2y ago
Thank you for the sanity check! I clearly have lost it
Alexicon
Alexicon2y ago
it happens to everyone, no problem