使用Mvvm,Wpf,C#,Visual Studio

时间:2019-04-16 11:26:51

标签: c# wpf mvvm

我想对TextChange事件执行一个方法,对于特定的文本,我想做一些事情并使用MVVM关闭窗口

例如,在我这部分代码中,我想关闭窗口:

if (text.Equals("12345"))
{
   //Exit from window
}

我知道如何使用命令从按钮上做到这一点,就像下一个示例中的代码一样。

但是如何将窗口传递给绑定到文本框文本的运行属性?

还是有另一种关闭表格的方法?

我想在ViewModel上执行此操作,而不是在后面的代码中写我的代码,因为我可以使用MVVM模式关闭

我的XAML代码:

<Window x:Class="PulserTesterMultipleHeads.UserControls.TestWindows"
        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:PulserTesterMultipleHeads.UserControls"
        mc:Ignorable="d"
        Name="MainTestWindow"
        Title="TestWindows" Height="450" Width="800">
    <Grid>
        <StackPanel>

            <TextBox Text="{Binding Text,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></TextBox>

            <Button Command="{Binding EndTestExit}"
                    CommandParameter="{Binding ElementName=MainTestWindow}">Exit</Button>
        </StackPanel>
    </Grid>
</Window>

XAML背后的代码:

using PulserTesterMultipleHeads.Classes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace PulserTesterMultipleHeads.UserControls
{
    /// <summary>
    /// Interaction logic for TestWindows.xaml
    /// </summary>
    public partial class TestWindows : Window
    {
        public TestWindows()
        {
            InitializeComponent();
            DataContext = new TestWindowsMV();
        }
    }
}

查看模型代码:

using PulserTester.ViewModel.Base;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace PulserTesterMultipleHeads.Classes
{
    public class TestWindowsMV : INotifyPropertyChanged
    {
        private string text;
        public string Text {
            get {
                return text;
            } set {
                text = value;
                if (text.Equals("12345"))
                {
                    //Exit from window
                }

            }
        }


        /// <summary>
        ///  for the example
        /// </summary>
        private ICommand _EndTestExit;

        public ICommand EndTestExit
        {
            get
            {
                if (_EndTestExit == null)
                {
                    _EndTestExit = new GenericRelayCommand<Window>((window) => EndTestExitAction(window));
                }
                return _EndTestExit;
            }
        }

        private void EndTestExitAction(Window window)
        {
            window.Close();
        }


        public event PropertyChangedEventHandler PropertyChanged;
    }
}

*************************编辑为答案****************** ********** ModelView中的更改:

public string Text {
            get {
                return text;
            } set {
                text = value;
                if (text.Equals("12345"))
                {
                    CloseAction();
                }

            }
        }

后面代码的更改:

public TestWindows()
        {
            InitializeComponent();
            DataContext = new TestWindowsMV();

            if (((TestWindowsMV)DataContext).CloseAction == null)
                ((TestWindowsMV)DataContext).CloseAction = new Action(this.Close);

        }

3 个答案:

答案 0 :(得分:2)

使用MVVM有点困难,但是您可以做的是在ViewModel中创建一个Event并附加一个函数,该函数将在View后面的代码中关闭窗口。然后,只要您需要关闭窗口(或者执行其他比ViewModel更为方便的操作),就可以在ViewModel内部调用事件

答案 1 :(得分:0)

从ViewModel中关闭视图的最干净的方法是使用附加属性

public static class perWindowHelper
{
    public static readonly DependencyProperty CloseWindowProperty = DependencyProperty.RegisterAttached(
        "CloseWindow",
        typeof(bool?),
        typeof(perWindowHelper),
        new PropertyMetadata(null, OnCloseWindowChanged));

    private static void OnCloseWindowChanged(DependencyObject target, DependencyPropertyChangedEventArgs args)
    {
        if (!(target is Window view))
            return;

        if (view.IsModal())
            view.DialogResult = args.NewValue as bool?;
        else
            view.Close();
    }

    public static void SetCloseWindow(Window target, bool? value)
    {
        target.SetValue(CloseWindowProperty, value);
    }


    public static bool IsModal(this Window window)
    {
        var fieldInfo = typeof(Window).GetField("_showingAsDialog", BindingFlags.Instance | BindingFlags.NonPublic);
        return fieldInfo != null && (bool)fieldInfo.GetValue(window);
    }
}

然后您可以将其绑定到ViewModel中的适当属性

<Window
    x:Class="...

    vhelp:perWindowHelper.CloseWindow="{Binding ViewClosed}">



private bool? _viewClosed;
public bool? ViewClosed
{
    get { return _viewClosed; }
    set { Set(nameof(ViewClosed), ref _viewClosed, value); }
}

有关我最近的blog post的更多详细信息。

答案 2 :(得分:-1)

您几乎已经实现了所需的一切。您真正需要做的就是从设置员那里调用private void EndTestExitAction(Window window)并在构建过程中提供window的价值:

public string Text {
            get {
                return text;
            } set {
                text = value;
                if (text.Equals("12345"))
                {
                    EndTestExitAction(window)
                }

            }
        }

其中window是您的视图模型的属性。