Well, the title is not very descriptive because they do not how to name what I'm looking for. I'll try to explain it as best I can.
In the .xaml file, a control (Suppose a textbox), if you type "Text", this can not be used again property. If we write by hand, the compiler displays an error. Good already explained why I think it's now easier.
Suppose now that I have two (DependencyProperty.RegisterAttached ... ...) with the name "Propiedad_1" and "Propiedad_2" is possible, if I'm already using one, the other can not be used in the same control and vice versa?
2) Another question, within a dependency property of type string, is it possible to check if the String changed at some point (around trying to not use a variable and then comparing), I need to avoid spending a TexBox and avoid the textbox.TextChanged event.
Thanks!
EDIT
This is what I have now.
public static readonly DependencyProperty FilterSourceProperty =
DependencyProperty.RegisterAttached("FilterSource", typeof (TextBox), typeof (ListViewExtension),
new FrameworkPropertyMetadata(null, OnTextBoxTextChanged));
public static TextBox GetFilterSource(DependencyObject dObj)
{
return (TextBox) dObj.GetValue(FilterSourceProperty);
}
public static void SetFilterSource(DependencyObject dObj, TextBox value)
{
dObj.SetValue(FilterSourceProperty, value);
}
private static void OnTextBoxTextChanged(DependencyObject dObj, DependencyPropertyChangedEventArgs e)
{
var listView = dObj as ListView;
var textBox = e.NewValue as TextBox;
if ((listView == null) || (textBox == null)) return;
textBox.TextChanged += delegate(object sender, TextChangedEventArgs tcea)
{
var view = CollectionViewSource.GetDefaultView(listView.ItemsSource);
if (view == null) return;
view.Filter += item =>
{
...
...
...
...
};
};
}
In .XAML
<TextBox Name="TxtFilter"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
Text="{Binding Filter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" CharacterCasing="Upper"/>
<ListView Margin="0,5,0,0"
ItemsSource="{Binding Articles}"
IsSynchronizedWithCurrentItem="True"
SelectedItem="{Binding SelectedArticle}"
tools:ListViewExtension.FilterSource="{Binding ElementName=TxtFilter}">
In ViewModel
public string Filter
{
get { return _filter; }
set
{
if (_filter == value) return;
_filter = value;
RaisePropertyChanged();
}
}
What I need now is change the use of a "TextBox" by a string.
tools:ListViewExtension.FilterSource="{Binding Filter}"
Your question is fairly hard to understand, due to the lack of a good, minimal, complete code example as well as the poor English. The latter is understandable (though you must still do what you can to ensure you're communicating as well as possible), but the former definitely should be addressed.
Lacking those improvements, I will guess that your questions (both…for future reference, please do not post two different questions in the same post) amount to the following:
I have two attached properties, which I would like to make mutually exclusive in the XAML editor. Is this possible?
No. The behavior you're seeing applies only to a single property. The editor will complain if you try to set the same property more than once. But it's easy for it to do that, since all it has to do is check whether that property was already used in the element.
For two different properties that are supposed to be mutually exclusive, there's not any feasible way to modify the editor or compiler's behavior to check this.
As an alternative, consider implementing the two mutually-exclusive values as a single property, where that property can accept two different subclasses of a given type, and where those subclasses each represent one of the two mutually exclusive property types.
Can I optimize property updates, so that if a new value is assigned that is actually the same as the current value, no "property changed" event is raised?
Whether this is possible depends on how your code is actually written. In WPF, binding is supported through the use of DependencyProperty or INotifyPropertyChanged. Neither of these would imply a TextChanged event in an object for a Text property, which you stated is the event you don't want raised.
Note that in general, DependencyObject.SetValue() will suppress change notifications if the effective value (after coercion) has not actually changed. Note also that in most other cases, extra change notifications would not normally be a real performance issue.
Lacking a good code example, not much more advice on that second question can be offered.
If you feel that these answers don't reasonably or usefully address your questions, please improve your post so that it is more understandable.
EDIT:
With respect to the first question, and based on the code snippet you've provided (not complete), I would say that the simplest approach would be to make FilterSource have type object instead of TextBox, and then in OnTextBoxTextChanged(), check the type of the new value and handle appropriately. I.e. if it's a TextBox, do what you're doing now (mostly…see (*) below), and if it's a string instance, just configure the view's filter directly instead of putting the configuration into an event handler.
(*) note:
I see at least two areas of improvement in your OnTextBoxTextChanged() method:
There is no need to rebuild the Filter event handler just because the text's changed. Instead, you can just call Refresh() on the view. So in that approach, you would implement the event handler for the Filter event to always retrieve the TextBox.Text property value for filtering. You would subscribe to the event once, and then the event handler for TextChanged would just call Refresh().
In the string scenario, you'd use a Filter event handler that just filters using the string value, with no need to handle the (non-existent, of course) TextChanged event.
The bigger issue is that you only ever subscribe to the TextChanged event. If you only ever change the FilterSource property once, you'll never notice a problem, but it is a problem. If the property value is ever changed again, you should be unsubscribing the old event handler before subscribing a new one. If you make the change I describe above, where the TextChanged event handler is only calling Refresh(), the impact of this bug will be significantly reduced. But it's still a bug.
end of note.
As far as the second part of your question goes, I don't see a problem that needs solving. It's not clear whether you're concerned about the TextBox.Text property or the FilterSource property, but I think that neither property should generate change notifications if the newly set property value is the same as the old.
If you think differently, please provide a better code example (both minimal and complete) that illustrates clearly what actual problem occurs, along with a clear, precise explanation of what that problem is: how the code currently behaves, and how that's different from how you want it to.
Taking all of the above into account, I think your OnTextBoxTextChanged() method should look more like this:
private static void OnTextBoxTextChanged(DependencyObject dObj, DependencyPropertyChangedEventArgs e)
{
ListView listView = dObj as ListView;
if (listView == null) return;
var view = CollectionViewSource.GetDefaultView(listView.ItemsSource);
if (view == null) return;
if (e.NewValue is TextBox)
{
TextBox newValue = (TextBox)e.NewValue;
view.Filter += item =>
{
string filterString = newValue.Text;
// filter based on filterString, etc.
};
textBox.TextChanged += delegate(object sender, TextChangedEventArgs tcea)
{
view.Refresh();
};
}
else if (e.NewValue is string)
{
string filterString = (string)e.NewValue;
view.Filter += item =>
{
// filter based on filterString, etc.
};
}
else return;
}
For this to work, you'll of course have to change the type of your attached property from TextBox to object.
In the above, I did not bother to address the issue of unsubscribing from the TextChanged or Filter events. If you desire to fix that particular problem, it is relatively simple: you need to unsubscribe the old handlers from the events (for TextChanged, only if e.OldValue is TextBox is true of course).
Of course, to do this you'll need to store the old event handler delegate instances on a per-ListView object basis, e.g. in a dictionary or maybe even just having a private attached property (similar to the FilterSource property, but not visible to other code). That way, you can retrieve the delegate instances later to unsubscribe them from their events.
Related
In my View I have 8 checkboxes all bound to a different property in the Model, lets say bool port1 ... port8. The property changes when the concerned checkbox is clicked.
When the user checks or unchecks one of these checkboxes, I also execute a binded command 'SetPortCommand'. The command executes a function like SetPort(uint numPort, bool set)
My view looks like this:
<CheckBox x:Name="cbPort1" Content="port1" Command="{Binding SetPortCommand}">
<CheckBox.IsChecked>
<Binding Path="MyModel.Port1"/>
</CheckBox.IsChecked>
</CheckBox>
Behind the whole thing is quite slow hardware, so I would like to avoid calling the function SetPort() for each port. I could use 8 commands like SetPortCommand1 to SetPortCommand8, but that causes lots of duplicate code.
I had the following ideas, but I do not know how to implement it, neither which one wouldf be conform to MVVM.
idea would be to somehow pass a constant to the command, telling it which of the 8 ports it should check or uncheck. Is there a easy way to do this?
idea would be to somehow use the OnPropertyChanged()-Event to call the function in here.
Any help appreciated :-)
You could avoid exeucting the command and just call your method from each setter, e.g.:
private bool _port1;
public bool Port1
{
get { return _port1; }
set { _port1 = value; SetPort(); }
}
If the SetPort modifies the other properties, you could use a flag to determine whether it should be invoked:
private bool _setPort = true;
private bool _port1;
public bool Port1
{
get { return _port1; }
set
{
_port1 = value;
if (_setPort)
{
_setPort = false;
SetPort();
_setPort = true;
}
}
}
You could do the same thing in the Execute method of your command if you still want to use a command for some reason.
The _setPort field prevents the method from getting called for each source property.
Alternatively, you could also avoid setting the property in the method and instead set the backing field and raise the PropertyChanged event:
_port2 = true;
OnPropertyChanged(nameof(Port2));
This will bypass the setter and avoid calling the method.
With a checkbox, the usual approach is to bind ischecked and to act in that setter. This uses text rather than a bool, but you can see there's a method called in the setter. https://social.technet.microsoft.com/wiki/contents/articles/30564.wpf-uneventful-mvvm.aspx#Change_of_Variable
You have a repeating group of functionality in this set of check boxes.
The usual approach is to bind a list or observablecollection of viewmodels to the itemssource of an itemscontrol. Template that data out into your ui. Here you'd have checkboxes. Each of your row viewmodels would hold data about a port. Name and whatnot.
If you particularly want a command you could have an ICommand such as delegatecommand or relaycommand bound from either:
The row viewmodel - in which case that "knows" which port is to be acted on. And your code that does stuff with that port is in the row viewmodel.
or
To the window viewmodel, in which case the row viewmodel is the datacontext of the button and this is passed as a parameter to the ICommand.
Both these are common scenarios working with buttons and you should be able to find code googling.
Binding IsChecked would be simpler and is hence more usual though.
I want to be able to click ListView item, which then takes me to appropriate page. But since there doesn't exists anything like ClickedItem to go along with the ItemClick, I have to use the SelectedItem (to get the object of what the user clicked) and SelectionChanged to capture when it happens (because this is setup in a way that when user clicks, he makes a selection, which triggers this).
Since in MVVM I can't use events, I'm binding what would be events to methods in my ViewModel.
<GridView x:Name="MyGrid"
ItemsSource="{x:Bind ViewModel.myList, Mode=OneWay}"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
IsSwipeEnabled="false"
SelectedItem="{Binding mySelectedItem, Mode=TwoWay}" // Binding makes it easier to bind the whole object
SelectionChanged="{x:Bind ViewModel.SelectioMade}"
>
I fill up my list in the ViewModel. I'm using Template10 implementation of INotifyPropertyChanged.
private MyListItemClass _mySelectedItem;
public MyListItemClass mySelectedItem{
get { return _mySelectedItem; }
set { Set(ref _mySelectedItem, value); }
}
And this simple method pushes me to the next page when user clickes on an item.
public void SelectioMade() {
if (_mySelectedItem != null) {
NavigationService.Navigate(typeof(Views.DetailPage), _mySelectedItem.id);
}
}
This works.
Problem is that a selection is made and it persists. When I hit the back button on the DetailPage, I go back to this list as I left it and the clicked item is still selected. And hence, clicking it again doesn't actually make a selection and trigger the SelectionChanged.
Obvious choice seemed to be to just set mySelectedItem to null when I no longer need the value, but it doesn't work.
public void SelectioMade() {
if (_mySelectedItem != null) {
NavigationService.Navigate(typeof(Views.DetailPage), _mySelectedItem.id);
mySelectedItem = null;
}
}
I can't seem to be able to set it back to null. If I place a break point on the mySelectedItem = null; it just doesn't do anything. It does trigger the set { Set(ref _mySelectedItem, value); }, but the View doesn't update. Neither the clicked item becomes deselected, nor a TextBlock I bound to one of the mySelectedItem.id properties gets changed (or rather emptied).
I would like to know why doesn't this work and possibly how to fix it. My MVVM may not be perfect, I'm still learning. And while it may not be perfect, I'm not really looking for advice how to properly write MVVM. I want to know why this doesn't work, because in my opinion, it should work just fine.
It seems that GridView doesn't like the SelectedItem property being changed within the SelectionChanged handler (it could result in an infinite loop if guards are not used). You could instead set SelectedItem to null in the OnNavigatedTo handler for that page (or whatever the Template 10 equivalent of that is).
Also you don't really need to subscribe to the SelectionChanged event since you can detect this in the setter of your mySelectedItem property.
However, I think it is wrong to handle item clicks by listening for selection changed events because the selection can be changed by other means (up/down arrow key, or tab key, for example). All you want to do is to respond to an item click and obtain the clicked item, right? For this, you can x:Bind the ItemClick event to a method in your view model:
<GridView ItemClick="{x:Bind ViewModel.ItemClick}" SelectionMode="None" IsItemClickEnabled="True">
public void ItemClick(object sender, ItemClickEventArgs e)
{
var item = e.ClickedItem;
}
If you're uneasy about the ItemClick method signature in your view model, then you can make your own ItemClick behavior to execute a Command exposed in your view model with the command's parameter bound to the clicked item.
If you're not using behaviors for some reason, then you can make your own attached property instead, something like this:
public class ViewHelpers
{
#region ItemClickCommand
public static readonly DependencyProperty ItemClickCommandProperty =
DependencyProperty.RegisterAttached("ItemClickCommand", typeof(ICommand), typeof(ViewHelpers), new PropertyMetadata(null, onItemClickCommandPropertyChanged));
public static void SetItemClickCommand(DependencyObject d, ICommand value)
{
d.SetValue(ItemClickCommandProperty, value);
}
public static ICommand GetItemClickCommand(DependencyObject d)
{
return (ICommand)d.GetValue(ItemClickCommandProperty);
}
static void onItemClickCommandPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var listView = d as ListViewBase;
if (listView == null)
throw new Exception("Dependency object must be a ListViewBase");
listView.ItemClick -= onItemClick;
listView.ItemClick += onItemClick;
}
static void onItemClick(object sender, ItemClickEventArgs e)
{
var listView = sender as ListViewBase;
var command = GetItemClickCommand(listView);
if (command != null && command.CanExecute(e.ClickedItem))
command.Execute(e.ClickedItem);
}
#endregion
}
XAML doesn't require MVVM patterns to be used, which means there is lots of "missing" functionality that you need to write yourself to make MVVM easier for you (like the above ItemClick attached property). Maybe Template 10 provides some behaviors for you already? I'm not familiar with it.
My first instinct would be to check your Set method, to ensure that it is really sending the proper notification to the view. I am not familiar with the Template10 implementation, so it seems strange to me that you are not required to provide a property name with Set().
Beyond that, I would suggest that you go back to using Click rather than SelectionChanged, since that is the behavior you are actually interested in. You should read a bit about attached properties, which are a great way to accomplish tasks that would normally require code-behind without actually using code-behind. They make MVVM a lot more practical and a lot less hackish.
https://msdn.microsoft.com/en-us/library/ms749011(v=vs.110).aspx
An attached property, more or less, allows you to define a DependencyProperty that you can attach to any element in XAML, like your GridView. Because you get access to the Element in the setter, you are free to attach to its events. So, you can create an attached property with a delegate type, which will forward an event like click to the delegate. Back in the view, you bind it to your handler in the ViewModel like this:
<GridView something:MyAttachedProperties.ClickHandler="{Binding MyClickHandler}" />
Hope this helps!
SelectedIndex = -1, following your null set of the SelectedItem property? So yes another property would be required or make sure that caching is disabled for that page as well.
I've set-up 2-way binding between my form (it has 32 controls) and an instance of my class but each character entered in a TextBox has that 1/2 second delay which makes the application almost unusable.
When I use DataSourceUpdateMode.Never, the problem does not occur which clearly indicates the 2-way binding is the culprit.
Note that if I set DataSourceUpdateMode.Never for each control but one, the lag exists for that one control so it doesn't seem to be the number of bound controls that causes the issue.
parameterTagRecord = new PETParameterTagRecord(TagID);
baseTagNameTB.DataBindings.Add("Text", parameterTagRecord,
"BaseTagName", true, DataSourceUpdateMode.OnPropertyChanged);
And an extract of my class:
public class PETParameterTagRecord : PETBaseObject, INotifyPropertyChanged
{
private string _baseTagName = Constants.NullString;
public event PropertyChangedEventHandler PropertyChanged;
public string BaseTagName
{
get { return _baseTagName; }
set
{
_baseTagName = value;
NotifyPropertyChanged("BaseTagName");
}
}
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
What am I doing wrong?
It shouldn't be that slow, but there's an option where you can have the textbox change on key press or on lost focus. Try setting it to lost focus. Also in your setter, be sure to check that _baseTagName != value before setting and raising the event. That will slow things up a bunch as well.
So, first try changing your binding like this:
baseTagNameTB.DataBindings.Add("Text", parameterTagRecord,
"BaseTagName", true, DataSourceUpdateMode.OnValidation);
See this MSDN link: http://msdn.microsoft.com/en-us/library/system.windows.forms.datasourceupdatemode.aspx. This means that instead of every keypress causing the new string value to be pushed into the property, it will only do so on Validation (which happens as part of the control losing focus).
Second, change your property implementation to match this:
public string BaseTagName
{
get { return _baseTagName; }
set
{
if (_baseTagName != value) {
_baseTagName = value;
NotifyPropertyChanged("BaseTagName");
}
}
}
Right now you're raising the event whether the property has actually changed or not. That is also detrimental to performance.
I ran into the same exact issue with BindingSource. This has has nothing to do with the update mode or notifications being fired too often (though indirectly, it does). The current implementation causes every single bound element to refresh whenever any property changes. So the reason OnValidation is less of an issue is obvious, it happens less frequently.
Fairly easy to check, too. Add two counters, increase each whenever a getter is accessed or NotifyProperChanged is called. In my case, with roughly 40 elements, I'd be at 1/40 after loading the form. Add a character in a textbox, suddenly at 2/80. Keeping the key pressed, my app stopped being responsive. Once it finally caught up, the count stood at something ridiculous like 50/2000. All from one single element changing.
I might be wrong, but I don't see how this makes sense or could be the desired implementation. Why would I want to update the whole form when one element changes, defeats the point of binding specific elements in the first place.
I have a WPF / XAML Window that contains a ComboBox that is giving me problems.
The window's ComboBox is firing off the SelectionChanged event.
The Debugger callstack shows me that SelectionChanged is being called (indirectly) from the Window Constructor.
The problem is that the window has an event Window_Loaded, which does some final initialization of data-members. Because this final initialization isn't done yet, the SelectionChanged event fails with a null-reference exception.
There are several ways I could solve this, but I'd like to know the "most correct" way.
I could fully initialize all my data members in the constructor. This violates the concept of keeping constructors minimal.
I could code the SelectionChanged event handler to properly deal with some data-members being null. This is coding to deal with only a startup problem that will never occur once the Window is fully constructed.
I could make the data-members Lazy-Loaded, so they are not initialized by Window_Loaded, but rather when they are first accessed. Seems like a bit of work to solve a problem that could be solved more simply.
I assume I'm not the first person to deal with UI-events prior to the Window Loaded event. What is the preferred way to handle this?
I had a similar problem and while tracing through it I had an "a-ha" moment. I had a default value as "IsSelected", an OnChange event, and a custom loadSettings method. I blamed the settings method at first, but it turned out that having a default value selected triggered the OnChange event before a handful of the controls were loaded, including the parent combobox which was triggering the null reference. Once I removed the "IsSelected" and allowed the default value to be null/empty it worked fine and my loadSettings method took care of setting the default or last used value.
I usually deal with the (endlessly irritating) SelectionChanged problem like this:
bool mySettingSelectionChangedInCode;
private void SetMySettingComboBox(string value)
{
mySettingSelectionChangedInCode = true;
mySettingComboBox.SelectedItem = value;
mySettingSelectionChangedInCode = false;
}
private void mySettingComboBox_SelectionChanged(object sender, EventArgs args)
{
if (mySettingSelectionChangedInCode)
return;
//...
}
The most proper way would be to build your application using MVVM pattern. In that case you would not have to deal with those problems. But I realize that it is not always possible to just move to MVVM unless the project is in its very beginning state.
Anyway, the problem you describe I would solve by defining a flag like IsInitialized in your window and set it to true once you've completed the initialization in the Loaded event handler. Then, I would check that flag in the SelectionChanged handler and if it is False then return from method without doing anything (ignore the call).
This worked for me:
if (System.Windows.Application.Current.MainWindow.IsInitialized == true)
{
//Do something
}
This could happen because you've set the SelectedValue of the combobox after setting the ItemsSource property.
I have a simple Converter that adds a "+" symbol to a positive number that is entered in a TextBox. When the number is entered I want to initiate some action, but I don't want to wait until the TextBox loses focus: I want to update the binding immediately as the user enters the text.
The default behaviour of a TextBox is that when a user navigates away from the box, the binding source is updated (UpdateSourceTrigger=LostFocus). In this scenario, my converter works as expected, and the + is added. However, when I change it to the following, the + is never added.
<TextBox Text="{Binding Value, Converter={StaticResource PlusConverter}, UpdateSourceTrigger=PropertyChanged}" />
I can imagine that there is a good reason why my converter.Convert() method is not called. I would like to have the following behaviour:
When the users enters text, the source is updated immediately
When the TextBox loses focus, the + is added.
Now I'm looking for a nice, but especially GENERIC way of doing this (as I have a lot of these TextBoxes in my app).
So far I haven't been able to come up with a proper solution.
Agree w/Kent B, you need to post your Converter code.
I've been able to get part 1 to work with a simple converter (I'm binding a second unconverted TextBlock to show that the value is indeed getting updated).
However, if I understand your part 2, you're trying to get the TextBox's text to update with a "+" after it loses focus. This is a little trickier and I don't think you'll be able to do it with just an IConverter. If it can be done, I'd love to know the answer as well.
What you're essentially asking for is watermarked input behavior e.g. allow a user to enter some data, and have it get formatted correctly (both in the underlying DataBinding and in the UI). The quickest/dirtiest solution to this is to handle the TextBoxes' LostFocus but since you're using that all over your app, this may not be feasible.
You could also consider wrapping the TextBox in your own UserControl. If you look at WPFToolkit's implementation of a DatePicker it has similar behavior: allow the user to enter free form text, then auto-convert the value to a DateTime (if valid) and show the DateTime in a localized format.
HTH.
The other thing you might want to do, is edit the template for TextBox and move the actual PART_ContentHost to the right a bit, then have a TextBlock indicate the +/- part; i.e. change the template of the TextBox from:
Control
- Border
-- PART_ContentHost (the actual editing part)
into:
Control
- Border
-- Horizontal StackPanel
--- TextBlock (contains +/- sign, has 2px right margin)
--- PART_ContentHost (actual editable section)
Then, bind the TextBlock's content to the text, but with a converter that either writes a '+' or '-'. This way, the user can't delete the +/- part, and you don't have to worry about parsing it; this also makes it easier if you want to do something like make the negative sign red or something.
Thanks for your answers! I looked into this issue myself a bit futher and came up with the following solution (which I'm not entirely satisfied with, but it works fine)
I've created a CustomControl that adds functionality to the TextBox.
It provided an event handler for the LostFocus event
When this event occurs, my converter is called.
However, the way I resolve the Converter is not very satisfying (I take it from the Style that is associated with my TextBox). The Style has a Setter for the Text property. From that setter I can access my Converter.
Of course I could also make a "PlusTextBox", but I use different converters and I wanted a generic solution.
public class TextBoxEx : TextBox
{
public TextBoxEx()
{
AddHandler(LostFocusEvent,
new RoutedEventHandler(CallConverter), true);
}
public Type SourceType
{
get { return (Type)GetValue(SourceTypeProperty); }
set { SetValue(SourceTypeProperty, value); }
}
// Using a DependencyProperty as the backing store for SourceType. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SourceTypeProperty =
DependencyProperty.Register("SourceType", typeof(Type), typeof(TextBoxEx), new UIPropertyMetadata(null));
private static void CallConverter(object sender, RoutedEventArgs e)
{
TextBoxEx textBoxEx = sender as TextBoxEx;
if (textBoxEx.Style == null) {
return;
}
if (textBoxEx.SourceType == null) {
}
foreach (Setter setter in textBoxEx.Style.Setters) {
if (setter.Property.ToString() == "Text") {
if (! (setter.Value is Binding) ) {
return;
}
Binding binding = setter.Value as Binding;
if (binding.Converter == null) {
return;
}
object value = binding.Converter.ConvertBack(textBoxEx.Text, textBoxEx.SourceType, binding.ConverterParameter, System.Globalization.CultureInfo.CurrentCulture);
value = binding.Converter.Convert(value, typeof(string), binding.ConverterParameter, System.Globalization.CultureInfo.CurrentCulture);
if (!(value is string)) {
return;
}
textBoxEx.Text = (string)value;
}
}
}
}
In your converter, couldn't you just check the keyboard's current focus? Something like:
TextBox focusedTextBox = Keyboard.FocusedElement as TextBox;
if (focusedTextBox == null || focusedTextBox != senderOrWhatever)
{
' this is where you'd add the +, because the textbox doesn't have focus.
}