Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# NotifyPropertyChanged和ContentControl_C#_Wpf - Fatal编程技术网

C# NotifyPropertyChanged和ContentControl

C# NotifyPropertyChanged和ContentControl,c#,wpf,C#,Wpf,我为我的问题挣扎了一个星期,我无法解决它。我正在编写一个MVVM WPF应用程序,它只有一个窗口(MainView)。在这个main视图中我想在需要时加载不同的UserControl。在应用程序启动中我正在加载MainViewModel。在MainViewModel的构造函数中,我正在加载第一个ViewModel(LoginViewModel)。我的MainView.xaml的原因是它显示了我想要的Login用户控件。所以直到现在一切都很好。在ActivePanel类中我正在保存CurrentV

我为我的问题挣扎了一个星期,我无法解决它。我正在编写一个MVVM WPF应用程序,它只有一个窗口(MainView)。在这个
main视图中
我想在需要时加载不同的
UserControl
。在
应用程序启动中
我正在加载
MainViewModel
。在
MainViewModel
的构造函数中,我正在加载第一个
ViewModel
LoginViewModel
)。我的
MainView.xaml的原因是它显示了我想要的
Login用户控件。所以直到现在一切都很好。在
ActivePanel类中
我正在保存
CurrentView
,因为在我的
MainView.xaml中,我正在为
ContentControl
绑定到我的
CurrentView
。因此,除了视图的更改之外,一切都在工作,尽管
CurrentView
NotifyPropertyChanged
方法正在工作。我在想,我的错误在于
xaml
(数据绑定)。希望你们能帮助我

这是我的
MainView.xaml
,我想在其中加载不同的数据模板。就像我之前说过的:通过
MainViewModel
的构造函数加载
LoginViewModel
正在工作。更改为其他
VieModels
也在起作用,但将数据绑定到
ContentControl
是这里的大问题

<Window x:Class="App.View.MainView"
        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:App.View"
        mc:Ignorable="d"
        xmlns:viewmodels="clr-namespace:App.ViewModels"
        xmlns:views="clr-namespace:App.View"
        xmlns:helper="clr-namespace:App.Helper"
        Title="Betrooms" Height="500" Width="350">

    <Window.Resources>
        <DataTemplate x:Name="LoginUCTemplate" DataType="{x:Type viewmodels:LoginViewModel}">
            <views:LoginUC DataContext="{Binding}"/>
        </DataTemplate>

        <DataTemplate x:Name="RegUCTemplate" DataType="{x:Type viewmodels:RegViewModel}">
            <views:RegUC DataContext="{Binding}"/>
        </DataTemplate>

        <DataTemplate x:Name="HomeUCTemplate" DataType="{x:Type viewmodels:HomeViewModel}">
            <views:HomeUC DataContext="{Binding}"/>
        </DataTemplate>
    </Window.Resources>

    <Window.DataContext>
        <viewmodels:ActivePanel/>
    </Window.DataContext>

    <Grid>
        <ContentControl Content="{Binding CurrentView, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"/>
    </Grid>
</Window>
这是我的
MainViewModel

namespace App.ViewModels
{
    public class MainViewModel : ActivePanel
    {
        private LoginViewModel _loginViewModel;

        public MainViewModel()
        {
            _loginViewModel = new LoginViewModel();
            CurrentView = _loginViewModel;
        }
    }
}
这是我的
LoginViewModel
,在这里我通过一个动作更改
CurrentView
的值:

namespace App.ViewModels
{
    public class LoginViewModel : ActivePanel
    {
        #region Member
        private string _username;
        private string _password;
        bool login = false;

        private HomeViewModel _homeViewModel;
        private RegViewModel _regViewModel;

        UserModel User = new UserModel();
        #endregion

        #region Properties
        public ICommand RegActionCommand { get; set; }
        public ICommand LogActionCommand { get; set; }

        public string GetUsername
        {
            get { return _username; }
            set
            {
                if (value != _username)
                {
                    _username = value;
                    OnPropertyChanged("GetUsername");
                }
            }
        }

        public string GetPassword
        {
            get { return _password; }
            set
            {
                if (value != _password)
                {
                    _password = value;
                    OnPropertyChanged("GetPassword");
                }
            }
        }
        #endregion

        #region Constructor
        public LoginViewModel()
        {
            this.RegActionCommand = new RelayCommand(RegAction);
            this.LogActionCommand = new RelayCommand(LogAction);
        }
        #endregion

        #region Button-Action
        private void LogAction(object obj)
        {               
                _homeViewModel = new HomeViewModel();
                CurrentView = _homeViewModel;
        }

        private void RegAction(object obj)
        {
            _regViewModel = new RegViewModel();
            CurrentView = _regViewModel;
        }
        #endregion           
    }
}
我希望我的问题是可以理解的:
ContentControl
绑定设置为
CurrentView
,但是
ContentControl
永远不会改变,尽管
CurrentView
的属性在改变


谢谢大家。干杯,保罗。

在命令处理程序中,您正在更改
LoginViewModel
CurrentView
属性。
ContentControl
DataContext
MainViewModel
,因此它的内容绑定到
MainViewModel
CurrentView
属性

您需要在命令处理程序中设置
MainViewModel
的属性。有不同的方法可以实现这一点,例如,您可以向
LoginViewModel
添加构造函数参数,以传递对
MainViewModel
的引用。您可以保存此引用,然后在命令处理程序中访问它


另一种可能是从
LoginViewModel
中的命令引发事件或发送消息,并在
MainViewModel
中处理它。这将减少ViewModels之间的耦合,但取决于您使用的机制和库,这可能会稍微复杂一些。

您是否尝试过在
ContentControl
下而不是在窗口资源下定义内容控制数据模板?我想我没有尝试过这样做。我对这种编码不是很熟悉。我尝试了很多在谷歌上找到的想法,但都不管用。您认为,您可以给出一个如何形成我的MainView.xaml的小例子吗?请注意,在单向绑定上设置
UpdateSourceTrigger=PropertyChanged
,是毫无意义的。它只对双向或单向ToSource绑定有影响。设置
Mode=OneWay
是多余的,因为这是默认设置。也就是说,您的代码应该如何工作?有一个
ActivePanel
实例被设置为主窗口的DataContext,其中一个
CurrentView
最初为空。该属性是如何变化的?感谢您提供有关{Mode=OneWay}的信息。我已经改变了。关于CurrentView的其他问题:正如我所理解的,我可以在运行时遵循CurrentView的值,是的,在程序开始时,该值为null,但构造函数会变成LoginVIewModel。当我点击die LoginView模型中的一个按钮时,CurrentView的值再次改变。因此,这一切都正常,但与CurrentView的绑定不起作用。我希望你能更详细地说明应该改变什么。干杯,保罗,谢谢你。我现在理解了我的代码中的错误。
namespace App.ViewModels
{
    public class LoginViewModel : ActivePanel
    {
        #region Member
        private string _username;
        private string _password;
        bool login = false;

        private HomeViewModel _homeViewModel;
        private RegViewModel _regViewModel;

        UserModel User = new UserModel();
        #endregion

        #region Properties
        public ICommand RegActionCommand { get; set; }
        public ICommand LogActionCommand { get; set; }

        public string GetUsername
        {
            get { return _username; }
            set
            {
                if (value != _username)
                {
                    _username = value;
                    OnPropertyChanged("GetUsername");
                }
            }
        }

        public string GetPassword
        {
            get { return _password; }
            set
            {
                if (value != _password)
                {
                    _password = value;
                    OnPropertyChanged("GetPassword");
                }
            }
        }
        #endregion

        #region Constructor
        public LoginViewModel()
        {
            this.RegActionCommand = new RelayCommand(RegAction);
            this.LogActionCommand = new RelayCommand(LogAction);
        }
        #endregion

        #region Button-Action
        private void LogAction(object obj)
        {               
                _homeViewModel = new HomeViewModel();
                CurrentView = _homeViewModel;
        }

        private void RegAction(object obj)
        {
            _regViewModel = new RegViewModel();
            CurrentView = _regViewModel;
        }
        #endregion           
    }
}