Click here to Skip to main content
15,887,175 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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:
XAML
<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:
XAML
<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:
C#
private void OpenFlyout(string selectType)
{
    Messenger.Default.Send<bool>(true, BroadcastMessageToken.ClassFlyout);
}

Code behind to set the focus:
C#
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();

            //btnSelectClass.Cursor = Cursors.Hand;
            break;
    }
}

interface code set the focus:
C#
public interface IRequestFocus
{
    event EventHandler<focusrequestedeventargs> FocusRequested;
}

public class FocusRequestedEventArgs : EventArgs
{
    public FocusRequestedEventArgs(string propertyName)
    {
        PropertyName = propertyName;
    }
    public string PropertyName { get; set; }
}

ViewModel code:
C#
public class SelectViewModel : ViewModelBase, IRequestFocus
{
 public event EventHandler<focusrequestedeventargs> FocusRequested;//VC01 11/13/2023

 protected virtual void OnFocusRequested(string propertyName)
 {
     FocusRequested?.Invoke(this, new FocusRequestedEventArgs(propertyName));
 }
}

Code to notify the changes for property
C#
private async Task SetSelectModel(string propertyName, object value)
{
    OnFocusRequested(nameof(Class));
}
Posted
Updated 20-Nov-23 22:00pm
v2

1 solution

One method could be using the MVVM Community Toolkit Messenger: Messenger - Community Toolkits for .NET | Microsoft Learn[^] - This allows for loosely coupled communication.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900