WPF - 如何处理从 MainWindow 中的 UserControl 引发的事件并更新 ViewModel [英] WPF - How to handle event raised from UserControl in MainWindow and update ViewModel

查看:37
本文介绍了WPF - 如何处理从 MainWindow 中的 UserControl 引发的事件并更新 ViewModel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在 UserControl1 中引发一个事件,但我不知道如何处理该事件以在 MainWindow 中显示 UserControl2.

I am trying to raise an event in UserControl1 but I could not figure out how to handle that event to display UserControl2 in MainWindow.

主窗口.xaml

<Window x:Class="WpfApp1.MainWindow"
        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:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">

    <Window.DataContext>
        <local:ViewModel1 />
    </Window.DataContext>

    <Window.Resources>
        <DataTemplate x:Key="Template1" DataType="{x:Type local:ViewModel1}">
            <local:UserControl1 />
        </DataTemplate>
        <DataTemplate x:Key="Template2" DataType="{x:Type local:ViewModel1}">
            <local:UserControl2 />
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <ContentControl Content="{Binding }">
            <ContentControl.Style>
                <Style TargetType="{x:Type ContentControl}">
                    <Setter Property="ContentTemplate" Value="{StaticResource Template1}" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding UserControlId}" Value="2">
                            <Setter Property="ContentTemplate" Value="{StaticResource Template2}" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>
    </Grid>
</Window>

MainWindow.cs

MainWindow.cs

using System.Windows;

namespace WpfApp1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

UserControl1.xaml

UserControl1.xaml

<UserControl x:Class="WpfApp1.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApp1"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Label Content="User Control 1" />
        <Button x:Name="btnNext" Content="Next" Click="btnNext_Click"></Button>
    </Grid>
</UserControl>

UserControl1.cs

UserControl1.cs

using System.Windows;
using System.Windows.Controls;

namespace WpfApp1
{
    public partial class UserControl1 : UserControl
    {
        public static readonly RoutedEvent MyEvent = EventManager.RegisterRoutedEvent(
            "MyEventName",
            RoutingStrategy.Bubble,
            typeof(RoutedEventHandler),
            typeof(UserControl1)
        );

        public event RoutedEventHandler LoginEventHandler
        {
            add { AddHandler(MyEvent, value); }
            remove { RemoveHandler(MyEvent, value); }

        }
        public UserControl1()
        {
            InitializeComponent();
        }

        private void btnNext_Click(object sender, RoutedEventArgs e)
        {
            var eventArgs = new RoutedEventArgs(MyEvent);
            RaiseEvent(eventArgs);
        }
    }
}

UserControl2.xaml

UserControl2.xaml

<UserControl x:Class="WpfApp1.UserControl2"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApp1"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Label Content="User Control 2" />
    </Grid>
</UserControl>

UserControl2.cs

UserControl2.cs

using System.Windows.Controls;

namespace WpfApp1
{
    public partial class UserControl2 : UserControl
    {
        public UserControl2()
        {
            InitializeComponent();
        }
    }
}

ViewModel1.cs

ViewModel1.cs

using System.ComponentModel;

namespace WpfApp1
{
    public class ViewModel1 : INotifyPropertyChanged
    {
        public int UserControlId { get; set; }

        public ViewModel1()
        {
            UserControlId = 2;
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}

我想我必须更新 ViewModel1 中的 UserControlId 属性才能更改用户控件,但是在哪里处理以及如何获取 ViewModel1 实例来更改属性?

I think i have to update the UserControlId property in ViewModel1 to change the user control but where to handle and how to get the ViewModel1 instance to change the property?

编辑 1抱歉,ViewModel1 构造函数中的错字,我的意思是将 UserControlId 属性初始化为 1,而不是 2.

EDIT 1 Sorry for the typo in the ViewModel1 constructor, i meant to initialize the UserControlId property to 1, not 2.

当我运行它时,我看到在主窗口中加载了 UserControl1 的窗口.UserControl1 有一个按钮下一步".单击 UserControl1 中的按钮时,我想显示 UserControl2.所以我在按钮单击事件处理程序中引发 MyEvent 路由事件.现在,在哪里附加和编写 MyEvent 的事件处理程序以及如何获取 ViewModel1 实例以更改其 UserControlId 属性?

When i run this, i see the window with UserControl1 loaded in the main window. UserControl1 is having a button "Next". On clicking the button in UserControl1, i want to show UserControl2. So I am raising MyEvent routed event inside button click event handler. Now, where to attach and write the event handler for MyEvent and how to get the ViewModel1 instance to change it's UserControlId property?

推荐答案

我终于让这个工作了.引发的事件在 ViewModel1 中更改为属性名称,在 MainWindow 中添加了事件侦听器,

I finally got this to work. Raised event changed with property name in ViewModel1, added event listener in MainWindow,

这是更改后的文件

ViewModel1.cs

ViewModel1.cs

using System.ComponentModel;

namespace WpfApp1
{
    public class ViewModel1 : INotifyPropertyChanged
    {
        private int _userControlId;

        public int UserControlId { 
            get { return _userControlId; }

            set 
            {
                _userControlId = value;
                RaisePropertyChanged("UserControlId");
            }
        }

        private void RaisePropertyChanged(string v = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(v));
        }

        public ViewModel1()
        {
            UserControlId = 1;
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}

MainWindow.cs

MainWindow.cs

using System.Windows;

namespace WpfApp1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            AddHandler(UserControl1.MyEvent, new RoutedEventHandler(OnMyEvent));
        }

        private void OnMyEvent(object sender, RoutedEventArgs e)
        {
            var vm = (ViewModel1)DataContext;
            vm.UserControlId = "2";
        }
    }
}

这篇关于WPF - 如何处理从 MainWindow 中的 UserControl 引发的事件并更新 ViewModel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆