我已经在使用MVVM模式的WPF应用程序中进行了几天的开发工作。我也是WPF和MVVM模式的新手。

在我的方案中,我有一个用户控件 View (名为EPayView.xaml),该 View 具有一个接受电话号码的文本框。该 View 具有一个对应的 View 模型(名为EPayViewModel.cs)。在MainWindow.xaml中,我有一个用户控件( float 虚拟键盘),该控件是从 namespace 控件WpfKb.Controls派生的。 MainWindow.xaml还具有一个对应的 View 模型(名为MainViewModel.cs)

话虽如此,我已经完成了有关如何使用附加的依赖项属性的研究,这使我找到了这种解决方案。 Set focus on textbox in WPF from view model (C#),我认为这是我可以在EPayView.xaml文本框中绑定(bind)属性IsFocused的地方。

以下是我已经合并到解决方案中的代码。

EpayView.xaml(文本框xaml标记)

<TextBox Text="{Binding PhoneNo}" Grid.Row="5" Margin="10,0,10,0" VerticalContentAlignment="Center" FontSize="12" x:Name="Email" behaviors:FocusExtension.IsFocused="{Binding IsFocused, Mode=TwoWay}"/>

MainWindow.xaml(xaml标记)
<Window x:Class="SmartPole540.View.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="clr-namespace:WpfKb.Controls;assembly=SmartPole.WpfKb"
    xmlns:wpf="clr-namespace:WebEye.Controls.Wpf;assembly=WebEye.Controls.Wpf.WebCameraControl"
    xmlns:utilities="clr-namespace:SoltaLabs.Avalon.Core.Utilities;assembly=SoltaLabs.Avalon.Core"
    xmlns:userControls="clr-namespace:SoltaLabs.Avalon.View.Core.UserControls;assembly=SoltaLabs.Avalon.View.Core"
    xmlns:square="clr-namespace:SmartPole.View.Square;assembly=SmartPole.View"
    xmlns:view="clr-namespace:SmartPole.View;assembly=SmartPole.View"
    Title="CitiPulse"
    WindowStartupLocation="Manual"
    PreviewMouseLeftButtonDown="Window_PreviewMouseLeftButtonDown"
    Name="mainWindow">

    <userControls:RollPanel.BottomContent>
        <square:SquareView Canvas.Top="1010" DataContext="{Binding DataContext.SquareViewModel,
            RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type userControls:RollPanel}}}"/>
    </userControls:RollPanel.BottomContent>

    <controls:FloatingTouchScreenKeyboard
            x:Name="floatKb" Width="500" Height="250" PlacementTarget="{Binding ElementName=MainGrid}"
            Placement="Center" AreAnimationsEnabled="False" Visibility="Visible"
            IsOpen="{Binding IsChecked, ElementName=kbButton}"/>
</Window>

在上面的代码中,用户控件RollPanel.BottomContent在另一个名为RollPanel.xaml的 View 中承载EPayView.xaml View 。

EpayViewModel.cs包含IsFocused附加属性的静态类FocusExtension(请参阅此解决方案-Set focus on textbox in WPF from view model (C#))。而且,EPayViewModel.cs已经实现了INotifyPropertyChanged,它包装在接受T类型的具体类ObservableObject中。这与MainViewModel.cs相同
public class EPayViewModel : ObservableObject<EPayViewModel>, IPaymentViewModel, IActiveViewModel
{ ... }

public class MainViewModel : ObservableObject<MainViewModel>
{ ... }

因此,我的目标是当EPayView.xaml中的文本框具有焦点时,将显示MainWindow.xaml中的 float 虚拟键盘(floatKb)。

我一直在继续进行操作(我一直在考虑是否可以在MainViewModel.cs内部调用EPayViewModel中的FocusExtension静态类满足要求?),我们将不胜感激。

干杯,

最佳答案

正如AnjumSKhan所说,要以MVVM方式对某些事件使用react,您必须使用Command。可以在EventTrigger中调用命令,您将需要添加对System.Windows.Interactvity组件的引用。
假设您有一个简单的View and View Model,并且需要在MainWindow中的TextBox获得焦点时显示此View。

View (NewWindow.xaml)

<Window x:Class="My.NewWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="NewWindow" Height="300" Width="300">
<TextBlock Text="{Binding Message}"/>

查看模型
public class NewWindowViewModel
{
    private string _message;
    public string Message
    {
        get { return _message; }
        set { _message = value; }
    }
}

您还有MainWindow,它是应用程序的主 View ,其中包含目标TextBox。您可能会看到有一个EventTrigger添加到TextBox,并且它具有属性InvokeCommandAction,该属性绑定(bind)到MainWindowViewModel的名为ShowCommand的命令。

主窗口
<Window x:Class="My.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" Title="MainWindow" Height="350" Width="525">
<TextBox Height="40" Text="{Binding Text}">
    <Interactivity:Interaction.Triggers>
        <Interactivity:EventTrigger EventName="GotFocus">
            <Interactivity:InvokeCommandAction Command="{Binding ShowCommand}"/>
        </Interactivity:EventTrigger>
    </Interactivity:Interaction.Triggers>
</TextBox>

在MainWindowViewModel的Show方法中,创建NewWindow View ,并获取新的NewWindowViewModel实例作为DataContext。 RelayCommand类在my answer to this question中提供

MainWindowViewModel
public class MainWindowViewModel
{
    private string _text;
    public string Text
    {
        get { return _text; }
        set { _text = value; }
    }

    private ICommand _increaseCommand;
    public ICommand ShowCommand
    {
        get
        {
            if (_increaseCommand == null)
            {
                _increaseCommand = new RelayCommand(
                p => true,
                Show);
            }
            return _increaseCommand;
        }
    }

    private void Show(object obj)
    {
        var w = new NewWindow();
        var nvm = new NewWindowViewModel();
        nvm.Message = "Test";
        w.DataContext = nvm;
        w.Show();
    }
}

剩下的就是创建一个新的MainWindowViewModel并为MainWindow设置一个DataContext。
public MainWindow()
{
    InitializeComponent();
    var mvm = new MainWindowViewModel();
    mvm.Text = "Focus me!";
    DataContext = mvm;
}

希望它会有所帮助。

关于wpf - 将输入控件(来自另一个用户控件)设置为在WPF中聚焦时,如何在MainWindow中显示 float 虚拟键盘(用户控件)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40965739/

10-12 14:53
查看更多