Focus error in TextBox with AppBarButton - UWP - c#

I am using this code to make a button in XAML within a MVVM project in UWP.
for this use this code:
<CommandBar Background="Yellow" >
<AppBarButton Label="Pruebas" Command="{Binding cmd_Process}" >
<AppBarButton.Icon>
<SymbolIcon Symbol="Setting"/>
</AppBarButton.Icon>
</AppBarButton>
</CommandBar>
At the moment of "clicking" the 'Command' the method that I need is executed in the ViewModel, but I have to send a content of a TextBlock to work with it in the ViewModel.
All good, but at the time of sending it sends me null, so that I do not send null I have to change the configuration of the Focus to the TextBlock, but I have to do it first, and then execute the Command.
If I use a normal button to link the Command works perfect, but not with the AppBarButton.
How do I make the AppBarButton change the focus of the TextBlock before executing the Command? Or how do I control the fucus from the ViewModel, knowing that I have to call the page from the ViewModel class?

you can set the focus through ViewModel or even from your page class before executing the command or within the command function. with Control.Focus() method. more info in the links below :
https://learn.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.control.focus
https://learn.microsoft.com/en-us/uwp/api/windows.ui.xaml.input.focusmanager
https://learn.microsoft.com/en-us/windows/communitytoolkit/developer-tools/focustracker

You Can Lost the Focus in the TextBox with te property:
UpdateSourceTrigger=PropertyChanged
use into the TextBox... Example:
<TextBox x:Name="txt_Name" Header="Name:" Margin="5" Text="{Binding PropertyBindingToViewModel, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

Related

How to empty a textbox in MVVM environment UWP C#

I have several textboxes that are filled when adding a new record. If I cancel the adding before saving the record, only the textboxes are filled with content. I want to empty these boxes when canceling the action. I have a button to cancel the action. This button is bound to the Viewmodel on the Click action. I considered to use the code behind for this clearing action but I see no way of reaching the code behind from the viewmodel in My MVVM approach
<TextBox
Header="Coach"
PlaceholderText="naam coach"
Margin="8,8,16,8"
MinWidth="200"
x:Name="NaamTextBox"
Text="{x:Bind Viewmodel.NewCoach.Naam, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox
Header="Telefoon"
PlaceholderText="telefoon"
Margin="8,8,16,8"
MinWidth="200"
x:Name="TelefoonTextBox"
Text="{x:Bind Viewmodel.NewCoach.Telefoon, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<AppBarButton x:Name="DeleteNewRecord" Click="{x:Bind Viewmodel.DeleteNewRecord}" Icon="Cancel"/>
<AppBarButton x:Name="SaveNewRecord" Click="{x:Bind Viewmodel.SaveNewRecord}" Icon="Save"/>
I considered to use the code behind for this clearing action but I see no way of reaching the code behind from the viewmodel in my MVVM approach. Is there a simple way to clear data on a form before it's used by the viewmodel?

Changing property IsIndeterminate on MaterialDesign button in WPF

I'm using a material design button in WPF and I'm not quite sure how to control the property IsIndeterminate from within C# code as the below does not work, like it usually does with "standard" properties like Content etc.
BTN_Search.materialDesign:ButtonProgressAssist.IsIndeterminate = true;
The WPF for the button below:
<Grid Width="124" Margin="5" VerticalAlignment="Center">
<Button Style="{StaticResource MaterialDesignRaisedButton}"
materialDesign:ButtonProgressAssist.Value="-1"
materialDesign:ButtonProgressAssist.IsIndicatorVisible="True"
materialDesign:ButtonProgressAssist.IsIndeterminate="False"
Content="Search"
Margin="2,0"
IsEnabled="{Binding DataContext.ControlsEnabled, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"
x:Name="BTN_Search"
Click="Search_Click"/>
</Grid>
I want the materialDesign:ButtonProgressAssist.IsIndeterminate property to be changed in the Click event when the button is pressed and then once I am done processing I need to change it back to False.
It is a dependency property so it can be set like this:
ButtonProgressAssist.SetIsIndeterminate(BTN_Search, true);
There is other examples on Github in the MaterialDesignInXamlTooking project https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/blob/master/MaterialDesignThemes.Wpf.Tests/ButtonProgressAssistTests.cs

Remove WPF IsDefault

I have 3 conrtols placed on my Window in WPF, each control contains one or more TextBox and Button, when a new control is selected I would like to change the IsDefault to that button. What I am currently doing is when the TextBox's GotFocus event is fired, I change my Button to IsDefault. This works the first time but when I change from one control to another, and back to the first selected control the second controls IsDefault is still true and when enter is pressed it fires the Click event on the incorrect control.
Is there a way that i can clear all IsDefault properties on my window or what is a better solution to my current way of doing this? See image below for example, when enter is pressed the Button with "..." is fired instead of quick search.
XAML (Update)
<odc:OdcTextBox Text="{Binding AccountNumber, UpdateSourceTrigger=PropertyChanged}" MinWidth="100" Name="txtAccountNumber" Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" Margin="{Binding TextMargin}">
<odc:OdcTextBox.Buttons>
<Button IsDefault="{Binding ElementName=txtAccountNumber, Path=IsKeyboardFocusWithin}" Width="30" Style="{StaticResource DionysusButton}" x:Name="btnCdv" Content="...">
</Button>
</odc:OdcTextBox.Buttons>
</odc:OdcTextBox>
<Button IsDefault={Binding IsKeyboardFocusWithin, ElementName=ThisGroupBox} />
EDIT:
Your code is slightly different in that you are providing buttons to some custom control. These buttons are declared in a different scope to where they end up (ie I assume they end up inside the OdcTextBox template somewhere). I suspect this is why WPF can't find the named element since that element is named in an outer scope.
You could try using RelativeSource to find the parent OdcTextBox instead:
<Button IsDefault="{Binding IsKeyboardFocusWithin, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type odc:OdcTextBox}}}"
Width="30" Style="{StaticResource DionysusButton}" x:Name="btnCdv" Content="...">
Similarly to how you're using the TextBox GotFocus event, you could do the inverse of this and use the LostFocus event to reset the IsDefault Property

Calling a command in my ViewModel from a binding to an event in my XAML?

I am currently writing a Windows 8 application. I am trying to call a method in my ViewModel. I want this method to be called when an item is double clicked. I have defined the following DataTemplate in my XAML to do this:
<DataTemplate x:Key="ItemTemplate">
<StackPanel Orientation="Horizontal">
<Image Width="185" Height="185" Stretch="Fill" Source="{Binding Path=Image}" DoubleTapped="{Binding Path=MethodIWishToBindTo}" IsDoubleTapEnabled="True" />
</StackPanel>
</DataTemplate>
The problem, of course, is the error message for my binding to MethodIWishToBindTo:
Invalid value for 'DoubleTapped'. Event values must be text
What is the best way for me to get around this ? I could call the method in the code-behind, however the method uses a property in my ViewModel, "SelectedItemInList", which I don't believe can be accessed from the code behind.
Can anyone offer me some advice for this problem ?
Thanks a lot.
You could use Interactivity and a custom behavior to trigger the event. Here's a post that topically covers an example:
MVVM-Light EventToCommand Behavior for CheckBox Checked/Unchecked in Silverlight
MVVM-Light definitely makes this easier, but it's possible without as well.
Here's an example of without: http://blog.roboblob.com/2010/01/26/binding-ui-events-from-view-to-commands-in-viewmodel-in-silverlight-4/

Silverlight MultiBinding with a converter, converter not firing after OnPropertyChange

I'm having some issues when using a converter with multiple bindings in a Silverlight project. The task is to disable a button when it is clicked, depending how four properties are evaluated in the custom converter.
The flow of the task is as follows:
Converter fired when initialising buttons
Button clicked and Command fired in ViewModel
Keep a record of the Id of the button in one viewModel property
In ViewModel fire OnPropertyChanged for one of the three view model properties
This should fire the converter
Everything is working apart from the last step. During the second last step, I can see the Property being accessed again after the OnPropertyChanged is fired. So I can't understand why the binding doesn't pick this change up and fire the converter. I'm thinking it may be due to the button item being in a datagrid and the bindings using Path & ElementName.
I'm using a MultiBinding solution for Silverlight 5 from here.
And I've seen this question but its solution isn't available in Silverlight (Binding.IndexerName).
So on the actual control I have a datagrid where each row has a textblock and a button.
The Button IsEnabled is bound to a Converter with three values from the ViewModel (properties A-C) and one from the datagrid.ItemSource (Id).
<Button Tag="{Binding Id}"
IsEnabled="{multibinding:MultiBinding Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged,
Source1={Binding Path=DataContext.PropertyA, ElementName=LayoutRoot},
Source2={Binding Path=DataContext.PropertyB, ElementName=LayoutRoot},
Source3={Binding Id},
Source4={Binding Path=DataContext.PropertyC, ElementName=LayoutRoot},
Converter={StaticResource myConverter}}">
The Button Click event is bound to a command on my viewModel.
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding Path=DataContext.ClickCommand, ElementName=LayoutRoot}"
CommandParameter="{Binding Id}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
Firing the OnPropertyChanged event in viewModel
public void OnClickCommand(int Id)
{OnPropertyChanged("PropertyA");}
I've actually just put a hack in place to refresh the whole control which will reinitialise and re-fire the converter but any help to solve this would be much appreciated.

Categories