如何使用WPF MVVM单击子窗口中的按钮取消隐藏父窗口的按钮 [英] How to unhide a button of parent window on clicking a button in the child window using WPF MVVM

查看:71
本文介绍了如何使用WPF MVVM单击子窗口中的按钮取消隐藏父窗口的按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用MVVM在WPF中创建了一个应用程序。我想在单击子窗口中的按钮时取消隐藏主窗口中的按钮。 


实际功能需要在单击其中的按钮和按钮时关闭子窗口在主窗口中将显示。


我做了很少的编码来实现相同的,但是,它不起作用。


在这里,是我的ViewModel和XAML


这是我的主视图模型


命名空间MyNameSpace

{

   公共类MainViewModel:INotifyPropertyChanged

    {

       公共事件PropertyChangedEventHandler PropertyChanged =(sender,e)=> {};

        private void OnOpenDialog(对象参数)

        {

            ChildViewModel vm = new ChildViewModel();

            Dialogs.DialogService.DialogResult result =

                Dialogs.DialogService.DialogService.OpenDialog(vm,参数为Window);

            this.itemVisible = vm.Result;

        }


       私人ICommand openDialogCommand = null;

       公共ICommand OpenDialogCommand

        {

            get {return this.openDialogCommand; }¥b $ b           设置{this.openDialogCommand = value; }¥b $ b        }


        private Visibility itemVisible;

        public Visibility ItemVisible

        {

           得到
            {

                return itemVisible;

            }¥b $ b           设为

            {

                if(itemVisible == value)

                   返回;

                itemVisible = value;



                PropertyChanged(this,new PropertyChangedEventArgs(" ItemVisible"));

            }¥b $ b        }¥b $ b    }
}



这是我的主要XAML窗口


< Window x:Class =" MyApplication.MainWindow"

  &NBSP; &NBSP; &NBSP; xmlns =" http://schemas.microsoft.com/winfx/2006/xaml/presentation"

  &NBSP; &NBSP; &NBSP; xmlns:x =" http://schemas.microsoft.com/winfx/2006/xaml"

  &NBSP; &NBSP; &NBSP;标题= QUOT;主窗口"高度= QUOT; 300"宽度="300">

  &NBSP; < StackPanel>

  &NBSP; &NBSP; &NBSP; <网格>

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < Grid.ColumnDefinitions>

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < ColumnDefinition Width =" *" />

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < ColumnDefinition Width =" *" />

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < /Grid.ColumnDefinitions>

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < Canvas Grid.Column =" 0"保证金="20 50 20 160">

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < Button Name =" btnSignIn"内容="登录" Command =" {Binding OpenDialogCommand}" CommandParameter =" {Binding RelativeSource = {RelativeSource AncestorType = Window}}"
/>

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < / Canvas>



  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < Canvas Grid.Column =" 1"保证金="20 50 20 160">

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < Button Visibility =" {Binding ItemVisible,Mode = TwoWay,UpdateSourceTrigger = PropertyChanged}"名称= QUOT; btnDeploy"含量="部署" />

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < / Canvas>

  &NBSP; &NBSP; &NBSP; < / Grid>

  &NBSP; < / StackPanel>

< / window>



子视图模型


命名空间MyNameSpace

{

  &NBSP; class ChildViewModel:INotifyPropertyChanged

  &NBSP; {

  &NBSP; &NBSP; &NBSP;公共事件PropertyChangedEventHandler PropertyChanged =(sender,e)=> {};
$


  &NBSP; &NBSP; &NBSP;公共ICommand SignInButtonCommand

  &NBSP; &NBSP; &NBSP; {

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; get {return new RelayCommand(SignIn); }¥b $ b  &NBSP; &NBSP; &NBSP; &NBSP;   

  &NBSP; &NBSP; &NBSP; }


  &NBSP; &NBSP; &NBSP; public void SignIn(object obj)

  &NBSP; &NBSP; &NBSP; {

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; string result = loginToServer.DoLogin(this.userName,this.password,"");

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; if(result.Equals("Success")))
  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; this.CloseDialogue(obj as Window);

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; this.result = Visibility.Visible;

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }¥b $ b  &NBSP; &NBSP; &NBSP; }


  &NBSP; &NBSP; &NBSP;公共活动EventHandler关闭;



  &NBSP; &NBSP; &NBSP; protected virtual void CloseView()

  &NBSP; &NBSP; &NBSP; {

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; var handler = Close;

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; if(handler!= null)handler(this,EventArgs.Empty);

  &NBSP; &NBSP; &NBSP; }


  &NBSP; &NBSP; &NBSP;私人ICommand m_CancelButtonCommand;

  &NBSP; &NBSP; &NBSP;公共ICommand CancelButtonCommand

  &NBSP; &NBSP; &NBSP; {

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; get {return new RelayCommand(Cancel); }¥b $ b  &NBSP; &NBSP; &NBSP; }


  &NBSP; &NBSP; &NBSP; public void取消(对象obj)

  &NBSP; &NBSP; &NBSP; {

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; this.CloseDialogue(obj as Window);

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; this.result = Visibility.Hidden;

  &NBSP; &NBSP; &NBSP; }


  &NBSP; &NBSP; &NBSP; private void CloseDialogue(窗口对话框)

  &NBSP; &NBSP; &NBSP; {

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; if(dialog!= null)

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; dialog.DialogResult = true;



  &NBSP; &NBSP; &NBSP; }


  &NBSP; &NBSP; &NBSP;私密可见性结果;

  &NBSP; &NBSP; &NBSP;公众可见性结果

  &NBSP; &NBSP; &NBSP; {

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;得到
  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;返回结果;

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }¥b $ b  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;设为

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; if(result!= value)

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;结果=价值;

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }¥b $ b  &NBSP; &NBSP; &NBSP; }¥b $ b  &NBSP; }
}


儿童XAML窗口


< Page x:Class =" MyApplication.ChildWindow"

  &NBSP; &NBSP; xmlns =" http://schemas.microsoft.com/winfx/2006/xaml/presentation"

  &NBSP; &NBSP; xmlns:x =" http://schemas.microsoft.com/winfx/2006/xaml"

  &NBSP; &NBSP; xmlns:mc =" http://schemas.openxmlformats.org/markup-compatibility/2006" 

  &NBSP; &NBSP; xmlns:d =" http://schemas.microsoft.com/expression/blend/2008" 

  &NBSP; &NBSP; xmlns:w =" clr-namespace:MyClass.Helper"

  &NBSP; &NBSP; mc:Ignorable =" d" 

  &NBSP; &NBSP; d:DesignHeight = QUOT; 300" d:DesignWidth =" 300"

Title =" ChildWindow">



  &NBSP; <网格>

  &NBSP; &NBSP; &NBSP; < Grid.ColumnDefinitions>

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < ColumnDefinition Width =" *" />

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < ColumnDefinition Width =" *" />

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < ColumnDefinition Width =" *" />

  &NBSP; &NBSP; &NBSP; < /Grid.ColumnDefinitions>



  &NBSP; &NBSP; &NBSP; < StackPanel Grid.Column =" 0">

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < TextBlock Name =" serverName" Text =" Server:"的Horizo​​ntalAlignment = QUOT;右"保证金=" 20,70,6,6" />

  &NBSP; &NBSP; &NBSP; < / StackPanel>

  &NBSP; &NBSP; &NBSP; < StackPanel Grid.Column =" 1" Horizo​​ntalAlignment =" Left">

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < ComboBox ItemsSource =" {Binding Server,Mode = TwoWay}" DisplayMemberPath =" ServerName"

  &NBSP; &NBSP; &NBSP; SelectedItem =" {Binding Path = SelectedServer,Mode = TwoWay,UpdateSourceTrigger = PropertyChanged}"

  &NBSP; &NBSP; &NBSP; 宽度=" 120"的Horizo​​ntalAlignment = QUOT;左" VerticalAlignment = QUOT;陀螺"保证金=" 0,70,0,0" />

  &NBSP; &NBSP; &NBSP; < / StackPanel>

  &NBSP; &NBSP; &NBSP; < StackPanel Grid.Column =" 0">

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < TextBlock Name =" userName" Text =" User Name:"的Horizo​​ntalAlignment = QUOT;右"保证金=" 20,100,6,6" />

  &NBSP; &NBSP; &NBSP; < / StackPanel>

  &NBSP; &NBSP; &NBSP; < StackPanel Grid.Column =" 1">

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < TextBox Name =" txtUserName"的Horizo​​ntalAlignment = QUOT;左"&NBSP;余量= QUOT; 0,100,0,0"宽度= QUOT; 120"高度= QUOT; 25" Text =" {Binding Path = UserName}" />

  &NBSP; &NBSP; &NBSP; < / StackPanel>

  &NBSP; &NBSP; &NBSP; < StackPanel Grid.Column =" 0">

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < TextBlock Name =" password" Text ="密码:"的Horizo​​ntalAlignment = QUOT;右"保证金=" 20,135,6,6" />

  &NBSP; &NBSP; &NBSP; < / StackPanel>

  &NBSP; &NBSP; &NBSP; < StackPanel Grid.Column =" 1">

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < PasswordBox Name =" txtPassword"瓦特:PasswordBoxHelper.BindPassword = QUOT;真" w:PasswordBoxHelper.BoundPassword =" {Binding Path = Password,Mode = TwoWay,UpdateSourceTrigger = PropertyChanged}"
Horizo​​ntalAlignment =" Left" 余量= QUOT; 0,135,0,0"宽度= QUOT; 120"高度="25"&b
  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; PasswordChar = QUOT * QUOT; />

  &NBSP; &NBSP; &NBSP; < / StackPanel>

  &NBSP; &NBSP; &NBSP; < StackPanel Grid.Column =" 1">

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < Button Name =" btnSignIn"内容="登录"宽度= QUOT; 50"&NBSP;余量= QUOT; 6,175,0,0"的Horizo​​ntalAlignment = QUOT;左" Command =" {Binding Path = SignInButtonCommand}"

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; CommandParameter =" {Binding RelativeSource = {RelativeSource AncestorType = Window}}" />

  &NBSP; &NBSP; &NBSP; < / StackPanel>

  &NBSP; &NBSP; &NBSP; < StackPanel Grid.Column =" 1">

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < Button Name =" btnCancel"含量="取消]宽度= QUOT; 50"&NBSP;余量= QUOT; 6,175,12,0"的Horizo​​ntalAlignment = QUOT;右" Command =" {Binding Path = CancelButtonCommand}"

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; CommandParameter =" {Binding RelativeSource = {RelativeSource AncestorType = Window}}" />

  &NBSP; &NBSP; &NBSP; < / StackPanel>

  &NBSP; < / Grid>

< / Page>


单击"登录"按钮后,主窗口中的"部署"按钮将在成功登录时显示,同时子窗口将关闭。子窗口正在关闭,但是,主窗口中的"部署"按钮未被禁用
。 


为了实现所需的功能,我创建了一个属性我的子ViewModel并根据某些条件为其分配Visible和Hidden值。每当控件在关闭子窗口时传递给主ViewModel时,我将
我在子视图模型中创建的属性值分配给主ViewModel的另一个属性,并且此属性具有  PropertyChangedEventHandler。


无论如何,主ViewModel中的属性不会被触发。实现此功能需要在实现中进行哪些更改?请帮忙。



解决方案

嗨全部,


我已经实现了这项功能。我错过了一些项目的分配。


谢谢。 


I have created an application in WPF using MVVM. I want to unhide a button in the main window on clicking a button in the child window. 

The actual functionality requires to close the child window on clicking a button in it and the button in the main window will get visible.

I have done few coding to implement the same, however, it's not working.

Here, is my ViewModel and XAML

This is my main View Model

namespace MyNameSpace
{
    public class MainViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged = (sender, e) => { };
        private void OnOpenDialog(object parameter)
        {
            ChildViewModel vm = new ChildViewModel();
            Dialogs.DialogService.DialogResult result =
                Dialogs.DialogService.DialogService.OpenDialog(vm, parameter as Window);
            this.itemVisible = vm.Result;
        }

        private ICommand openDialogCommand = null;
        public ICommand OpenDialogCommand
        {
            get { return this.openDialogCommand; }
            set { this.openDialogCommand = value; }
        }

        private Visibility itemVisible;
        public Visibility ItemVisible
        {
            get
            {
                return itemVisible;
            }
            set
            {
                if (itemVisible == value)
                    return;
                itemVisible = value;

                PropertyChanged(this, new PropertyChangedEventArgs("ItemVisible"));
            }
        }
    }
}

Here is my main XAML window

<Window x:Class="MyApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="300" Width="300">
    <StackPanel>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width = "*" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Canvas Grid.Column="0" Margin="20 50 20 160">
                <Button Name="btnSignIn" Content="Sign In" Command="{Binding OpenDialogCommand}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Window}}" />
            </Canvas>

            <Canvas Grid.Column="1" Margin="20 50 20 160">
                <Button Visibility="{Binding ItemVisible, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Name="btnDeploy" Content="Deploy" />
            </Canvas>
        </Grid>
    </StackPanel>
</Window>

Child View Model

namespace MyNameSpace
{
    class ChildViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged = (sender, e) => { };

        public ICommand SignInButtonCommand
        {
            get { return new RelayCommand(SignIn); }
            
        }

        public void SignIn(object obj)
        {
            string result = loginToServer.DoLogin(this.userName, this.password, "");
            if (result.Equals("Success"))
            {
                this.CloseDialogue(obj as Window);
                this.result = Visibility.Visible;
            }
        }

        public event EventHandler Close;

        protected virtual void CloseView()
        {
            var handler = Close;
            if (handler != null) handler(this, EventArgs.Empty);
        }

        private ICommand m_CancelButtonCommand;
        public ICommand CancelButtonCommand
        {
            get { return new RelayCommand(Cancel); }
        }

        public void Cancel(object obj)
        {
            this.CloseDialogue(obj as Window);
            this.result = Visibility.Hidden;
        }

        private void CloseDialogue(Window dialog)
        {
            if (dialog != null)
                dialog.DialogResult = true;

        }

        private Visibility result;
        public Visibility Result
        {
            get
            {
                return result;
            }
            set
            {
                if (result != value)
                    result = value;
            }
        }
    }
}

Child XAML window

<Page x:Class="MyApplication.ChildWindow"
      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:w="clr-namespace:MyClass.Helper"
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"
Title="ChildWindow">

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width = "*" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <StackPanel Grid.Column="0">
            <TextBlock Name="serverName" Text="Server: " HorizontalAlignment="Right" Margin ="20,70,6,6"/>
        </StackPanel>
        <StackPanel Grid.Column="1" HorizontalAlignment="Left">
            <ComboBox ItemsSource="{Binding Server, Mode=TwoWay}" DisplayMemberPath="ServerName"
        SelectedItem="{Binding Path=SelectedServer, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
        Width="120" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,70,0,0"/>
        </StackPanel>
        <StackPanel Grid.Column="0">
            <TextBlock Name="userName" Text="User Name: " HorizontalAlignment="Right" Margin ="20,100,6,6"/>
        </StackPanel>
        <StackPanel Grid.Column="1">
            <TextBox Name="txtUserName" HorizontalAlignment="Left"  Margin="0,100,0,0" Width="120" Height="25" Text="{Binding Path=UserName}" />
        </StackPanel>
        <StackPanel Grid.Column="0">
            <TextBlock Name="password" Text="Password: " HorizontalAlignment="Right" Margin ="20,135,6,6"/>
        </StackPanel>
        <StackPanel Grid.Column="1">
            <PasswordBox Name="txtPassword" w:PasswordBoxHelper.BindPassword="True" w:PasswordBoxHelper.BoundPassword="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left"  Margin="0,135,0,0" Width="120" Height="25"
                       PasswordChar="*" />
        </StackPanel>
        <StackPanel Grid.Column="1">
            <Button Name="btnSignIn" Content="Sign In" Width="50"  Margin="6,175,0,0" HorizontalAlignment="Left" Command="{Binding Path=SignInButtonCommand}"
                    CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Window}}"/>
        </StackPanel>
        <StackPanel Grid.Column="1">
            <Button Name="btnCancel" Content="Cancel" Width="50"  Margin="6,175,12,0" HorizontalAlignment="Right" Command="{Binding Path=CancelButtonCommand}"
                    CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Window}}"/>
        </StackPanel>
    </Grid>
</Page>

On clicking the Sign In button, the Deploy button in the main window will get visible on successful login, and at the same time the child window will get closed. The child window is getting closed, however, the Deploy button in the main window is not getting disabled. 

To achieve the required functionality, I have created a property in my Child ViewModel and assigning Visible and Hidden value to it based on some condition. Whenever, the control is passing to the main ViewModel on closing the child window, I am assigning the value of the property which I have created in child view model to another property of main ViewModel and this property has PropertyChangedEventHandler.

Anyways, the property in the main ViewModel is not getting fired. What are the changes required in my implementation to achieve this functionality? Please help.

解决方案

Hi all,

I have implemented the functionality. Assignment of few items were missed by me.

Thank you. 


这篇关于如何使用WPF MVVM单击子窗口中的按钮取消隐藏父窗口的按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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