I am working with MVVM and i want to set the focus to textbox or button from popup window(Flyout) to parent windows using MVVM and WPF, i tried a lot, but not able to find any solution.
parent and child form is a User Control, and on a parent form there is button and when click on that button a flyout is being open and when selecting an item from that form the button should be selected or focused of parent form.
Please help
What I have tried:
Flyout code:
<Controls:MetroWindow.Flyouts>
<Controls:FlyoutsControl>
<Controls:Flyout Style="{StaticResource flyout}" IsOpen="{Binding IsClassFlyoutOpen}" >
<Views:SelectClass></Views:SelectClass>
</Controls:Flyout>
</Controls:FlyoutsControl>
</Controls:MetroWindow.Flyouts>
parent form code is below:
<UserControl x:Class="GA.Recovery.UI.Views.Select"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ignore="http://www.galasoft.ch/ignore"
xmlns:common="clr-namespace:GA.Recovery.UI.AppHelpers"
mc:Ignorable="d ignore"
xmlns:Views="clr-namespace:GA.Recovery.UI.Views"
xmlns:model="clr-namespace:GA.Recovery.UI.Model"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:cmd="http://www.galasoft.ch/mvvmlight"
DataContext="{Binding SelectViewModel, Source={StaticResource Locator}}" Loaded="UserControl_Loaded">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto" />
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Views:SelectReadOnly x:Name="selectReadOnlyView" Grid.Column="0" Grid.Row="0" Grid.RowSpan="6" />
<Button Focusable="True" Name="btnSelectClass" TabIndex="17" Grid.Column="1" Grid.Row="0" Content="Select" Style="{StaticResource btn-primary}" Width="90" Margin="10,0,0,0" VerticalAlignment="Bottom"
Command="{Binding OpenFlyoutCommand}" CommandParameter="Class" Click="btnSelectClass_Click">
<Button.ToolTip>
<ToolTip Content="Select Class" Style="{StaticResource tooltip}"></ToolTip>
</Button.ToolTip>
</Button>
<Button TabIndex="18" Grid.Column="2" Grid.Row="1" Content="Select" Style="{StaticResource btn-primary}" Width="90" Margin="10 2, 0, 3" >
<Button.ToolTip>
<ToolTip Content="Select Sub Class" Style="{StaticResource tooltip}"></ToolTip>
</Button.ToolTip>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding OpenFlyoutCommand}" CommandParameter="Subclass" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<Button TabIndex="19" Name="btnSelectMfg" Grid.Column="2" Grid.Row="2" Content="Select" Style="{StaticResource btn-primary}" Width="90" Margin="10 2, 0, 3"
Command="{Binding OpenFlyoutCommand}" CommandParameter="Manufacturer" >
<Button.ToolTip>
<ToolTip Content="Select Mfg" Style="{StaticResource tooltip}"></ToolTip>
</Button.ToolTip>
</Button>
<Button TabIndex="20" Name="btnSelectModel" Grid.Column="2" Grid.Row="3" Content="Select" Style="{StaticResource btn-primary}" Width="90" Margin="10 2, 0, 3"
>
<Button.ToolTip>
<ToolTip Content="Select Model" Style="{StaticResource tooltip}"></ToolTip>
</Button.ToolTip>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding OpenFlyoutCommand}" CommandParameter="Model" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<Button TabIndex="22" Name="btnSelectAttributes" IsEnabled="{Binding AttributButtonEnable}" Grid.Column="2" Grid.Row="5" Content="Select" Style="{StaticResource btn-primary}" Width="90" Margin="10 2, 0, 3"
Command="{Binding OpenFlyoutCommand}" CommandParameter="Attribute" >
<Button.ToolTip>
<ToolTip Content="Select Attributes" Style="{StaticResource tooltip}"></ToolTip>
</Button.ToolTip>
</Button>
</Grid>
</UserControl>
Open the flyout code:
private void OpenFlyout(string selectType)
{
Messenger.Default.Send<bool>(true, BroadcastMessageToken.ClassFlyout);
}
Code behind to set the focus:
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
IRequestFocus focus = (IRequestFocus)DataContext;
focus.FocusRequested += OnFocusRequested;
}
private void OnFocusRequested(object sender, FocusRequestedEventArgs e)
{
switch (e.PropertyName)
{
case "Class":
Keyboard.Focus(btnSelectClass);
btnSelectClass.Focusable = true;
btnSelectClass.IsTabStop = true;
btnSelectClass.Focus();
break;
}
}
interface code set the focus:
public interface IRequestFocus
{
event EventHandler<focusrequestedeventargs> FocusRequested;
}
public class FocusRequestedEventArgs : EventArgs
{
public FocusRequestedEventArgs(string propertyName)
{
PropertyName = propertyName;
}
public string PropertyName { get; set; }
}
ViewModel code:
public class SelectViewModel : ViewModelBase, IRequestFocus
{
public event EventHandler<focusrequestedeventargs> FocusRequested;
protected virtual void OnFocusRequested(string propertyName)
{
FocusRequested?.Invoke(this, new FocusRequestedEventArgs(propertyName));
}
}
Code to notify the changes for property
private async Task SetSelectModel(string propertyName, object value)
{
OnFocusRequested(nameof(Class));
}