Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Binding updates for buttons from TextBoxHelper.ButtonCommand #3924

Closed
ghost opened this issue Sep 27, 2020 · 5 comments · Fixed by #3925
Closed

Binding updates for buttons from TextBoxHelper.ButtonCommand #3924

ghost opened this issue Sep 27, 2020 · 5 comments · Fixed by #3925
Milestone

Comments

@ghost
Copy link

ghost commented Sep 27, 2020

Describe the feature

I would like the bindings to be updated when clicking on the buttons created by "TextBoxHelper.ButtonCommand".

Additional context

Good afternoon,

i have a question about the behaviour of ButtonCommand in a textbox and the update of bindings.

Let us assume you have a textbox and a button. If the user enters something into the textbox and then clicks on the button to perform the action the button will have access to the value of the text property (which is assigned by the binding of the ViewModel). Since TextBox.Text has the default binding update to "LostFocus".

If you want to replace the following constellation with "TextBoxHelper.ButtonCommand" there is a problem. Clicking on the button does not create a LostFocus (which I had expected or hoped for) and the binding is not updated. This has the consequence that you can't access the property in the command.

Of course you could work around this as follows:

  • switch from "LostFocus" to "PropertyChanged"
  • pass text as parameter (which does not work in every case if the command is already used elsewhere)
  • Force update in every command you want to use

Couldn't we maybe add "UpdateSource" here:

https://github.com/MahApps/MahApps.Metro/blob/develop/src/MahApps.Metro/Controls/Helper/TextBoxHelper.cs#L895

Because I think that would reflect the expected behavior again? Or am I wrong?

Some example code

If you enter text into the TextBox and then click on the created button the MessageBox is empty. If you click on the dummy button before (through the LostFocus) the MessageBox shows the content of the TextBox.

<mah:MetroWindow x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls" xmlns:wpfapp1="clr-namespace:WpfApp1"
        Title="MainWindow"
        Width="400"
        SizeToContent="Height">
    <mah:MetroWindow.DataContext>
        <wpfapp1:SampleViewModel />
    </mah:MetroWindow.DataContext>

    <StackPanel>
        <!-- TextBox with button -->
        <TextBox Text="{Binding Path=TestString}" 
                 mah:TextBoxHelper.ButtonContent="s" 
                 mah:TextBoxHelper.ButtonCommand="{Binding Path=TestMessageCommand, Mode=OneWay}" 
                 Style="{DynamicResource MahApps.Styles.TextBox.Button}" />

        <!-- Dummy button to lose the focus  -->
        <Button>Click here to lose Focus</Button>
    </StackPanel>
</mah:MetroWindow>
public class SampleViewModel : BindableBase
    {
        private string _title;

        public string TestString
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        private ICommand _testMessageCommand;
        public ICommand TestMessageCommand => _testMessageCommand ?? (_testMessageCommand = new RelayCommand<object>((x) => MessageBox.Show(TestString), (x) => true));
    }
@ghost ghost added the Feature Request label Sep 27, 2020
@timunie
Copy link
Collaborator

timunie commented Sep 28, 2020

Hi @Rerago

I think your problem is this line:

You may try to copy the entire ControlTemplate and set Focusable=True. This may cause other problems, so be carefully.

Also please have a look into the Demo App. There is an example for Controls:TextBoxHelper.ButtonCommandParameter

<TextBox Name="test2"
Margin="{StaticResource ControlMargin}"
Controls:TextBoxHelper.ButtonCommand="{Binding TextBoxButtonCmdWithParameter, Mode=OneWay}"
Controls:TextBoxHelper.ButtonCommandParameter="{Binding ElementName=test2, Path=Text}"
Controls:TextBoxHelper.Watermark="Enter parameter"
Style="{DynamicResource MahApps.Styles.TextBox.Search}" />

Happy coding
Tim

@ghost
Copy link
Author

ghost commented Sep 28, 2020

Hi @timunie

I think that:

Focusable="False"

is totally ok at this point. But I think that we need an ".UpdateSource();" before executing the command. This should not break and should lead to an expected result.

Rerago

@timunie
Copy link
Collaborator

timunie commented Sep 28, 2020

@Rerago in the end @punker76 has to decide, but if you have a working solution (sounds like this) feel free to raise a pull request. Any contribution is welcome 😊

Happy coding
Tim

@ghost
Copy link
Author

ghost commented Sep 28, 2020

If @punker76 finds my idea in okay I like to do a PR.

But it would be nice if he says something about it. Not that I make the work unnecessary :).

But I just did it now (hope its fine^^):

#3925

Unfortunately I do not know which one would be the corresponding property in the rich text box. But the others are built in correctly.

@ghost
Copy link
Author

ghost commented Sep 29, 2020

So I have reworked my pull request again. I checked the other property and this one has the DefaultUpdateSourceTrigger not on LostFocus. And therefore no change is necessary here.

So the change is very small now.

@punker76 punker76 added this to the 2.2.1 milestone Oct 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging a pull request may close this issue.

2 participants