1

I found a number of examples on how to select a control from the view model but must not be searching on the right terms on how to get it to work the other way around. Basically I just want to have a boolean value in my view model updated when a text box is being edited and when it is not. I assume this is the same as wanting to know when it gets and looses focus.

So I have created a FocusExtension class as described here: Set focus on textbox in WPF from view model (C#)

But it is not triggering the accessors to my view model property "EditingMyTargetField" with the following line in my XAML:

my:FocusExtension.IsFocused="{Binding EditingMyTargetField}"
Community
  • 1
  • 1
user2027080
  • 115
  • 1
  • 10
  • Generally speaking, the ViewModel shouldn't really care that a value is *changing* (in the UI) but only when it has *changed*. If you are setting a flag for UI reasons only, it is ok to use the code-behind, or a trigger in the UI. – Wonko the Sane Dec 30 '13 at 21:59
  • The reason is because I want to enable a particular button when a textbox is being edited and disable it when it is not. I have the IsEnabled property bound to the CanExecute method of the Command pertaining to that button. That CanExecute method refers to a property in my ViewModel which needs to also be associated with whether or not the textbox is being edited. For another textbox I need to have one of my Commands behave one way if on the last textbox that makes up a form is selected and act a different way if it is not. (I don't control the app requirements). – user2027080 Dec 30 '13 at 22:04
  • One thing to keep in mind is that this behavior might be something you want to unit-test, in which case it most definitely is _not_ ok to use code-behind or triggers. – Mark Feldman Dec 30 '13 at 22:36

2 Answers2

2

I would explore the other answers besides the top answer, as others have improved upon the approved solution. I tested Zamotic's FocusExtension with a textbox and it successfully triggered the binding back to the viewmodel. His solution has events that trigger when the element gains or loses focus, that then sets the dependencyproperty value to the right state. I also had to explicitly state the binding mode as TwoWay in the markup, but you could alter the extension to set twoway binding by default if you wanted.

<TextBox local:FocusExtension.IsFocused="{Binding TextIsFocused, Mode=TwoWay}"/>
Kevin Nacios
  • 2,843
  • 19
  • 31
  • I'm thinking that the TwoWay option might be it, but it looks like my problem is that the FocusExtension methods are never getting fired or called when the control is created. Maybe something got lost in the C# to vb.net conversion. – user2027080 Jan 02 '14 at 14:31
  • Ok, I used the implementation of Zamotic from the link in my question above instead of the top voted one and it started working. – user2027080 Jan 02 '14 at 14:46
0

I modified my answer after going through your exact requirement.

You just need to use 2 events in this case when you want to enable your button when the mouse isOver the textbox and when its NOT.

Those 2 events are: MouseEnter and MouseLeave

These events capture the moment when the cursor is over the control and when its not.

And you need a bool property to bind to your Button inorder to change its Enablity according to the condition*(Mouse over or not)*.

private bool _isBtnEnable = false;

        public bool IsBtnEnable
        {
            get { return _isBtnEnable; }
            set
            {
                _isBtnEnable = value;
                OnPropertyChanged("IsBtnEnable");
            }
        }

And in Xaml:

  <Grid>
        <StackPanel Orientation="Horizontal">
            <TextBox Width="100" Text="{Binding 
Txt,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" 
 Mouse.MouseEnter="TextBox_MouseEnter" 
 Mouse.MouseLeave="TextBox_MouseLeave"/>
                <Button Width="70" Name="btn" Content="Save" Margin="20,0,0,0" 
IsEnabled="{Binding IsBtnEnable,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged
/>

        </StackPanel>

    </Grid>

And in Xaml.cs:

private void TextBox_MouseEnter(object sender, MouseEventArgs e)
        {
            IsBtnEnable = true;
        }

        private void TextBox_MouseLeave(object sender, MouseEventArgs e)
        { 

   if (string.IsNullOrEmpty(Txt)) (Checking if the TextBox is empty,remove it 
if regardless of text you want to disable the button on cursor being not over the
 TextBox but how will you click Save then because it will get disabled when you moved your mouse)
            IsBtnEnable = false;
        }

I think this will do the trick you want. :)

Vishal
  • 604
  • 1
  • 12
  • 25
  • Whether there is text or not in the textbox will not matter in this case as I need the behavior to be enabled or disabled if the cursor is present in the textbox regardless of what it contains. – user2027080 Jan 02 '14 at 14:34
  • The solution by Kevin meets all the requirements. I want to avoid code behind. Mouse behavior with respect to the text box is not important. It doesn't matter if the UI brings the textbox into focus or the user. The behavior should be the same. Simply binding to the IsFocused property of the control accomplishes all these things. Thank you for the solutions proposed. – user2027080 Jan 08 '14 at 22:05