从一些UserControl在WPF窗口中动态更改内容

时间:2018-05-21 08:04:23

标签: c# wpf user-controls

我有两个UserControl,例如LogInControlCheckControl。最初,窗口包含LogInControl,登录成功后登录窗口会更改:窗口包含CheckControl

来自MainWindow

的代码
public MainWindow()
        {
            InitializeComponent();

            LogInControl logInControl = new LogInControl();
            CheckControl checkControl = new CheckControl();
            logInControl.OnSuccessfulLogin += (senser, e) =>
            {
                ChangeContentControl("Check");
            };

            checkInControl.LogOutClick += (senser, e) =>
            {
                ChangeContentControl("LogIn");
            };
            this.contentControl.Content = logInControl;
        }

        public void ChangeContentControl(string kindContentControl)
        {
            switch (kindContentControl)
            {
                case "LogIn":
                    {
                        ...
                        this.contentControl.Content = new LogInControl();
                    }
                    break;
                case "Check":
                    {
                        ...
                        this.contentControl.Content = new CheckControl();
                    }
                    break;
            }
        }

来自LogInControl

的代码
public event EventHandler OnSuccessfulLogin;
private void loginButton_Click(object sender, RoutedEventArgs e)
        {
            OnSuccessfulLogin?.Invoke(this, e);
        }

它正常工作。但是'CheckControl'具有“Logout”按钮,当单击此按钮时,窗口中应该出现'LogInControl'内容。但它没有发生。

来自CheckControl

的代码
public event EventHandler LogOutClick;
        private void logOutButton_Click(object sender, RoutedEventArgs e)
        {
            LogOutClick?.Invoke(this, e);
        }
转换到LogOutClick的窗口时,

CheckInControl事件跟踪会停止(LogOutClick变为null)。 我不明白为什么会这样。请帮帮我。

2 个答案:

答案 0 :(得分:2)

您面临的问题是,当您切换控件时,您正在创建新控件。新的事件没有注册事件。因此,您将覆盖使用已注册事件创建的先前。

switch (kindContentControl)
{
    case "LogIn":
    {
        ...                           
        this.contentControl.Content = new LogInControl(); <- here
                                      ^^^------------
    }
    break;

    case "Check":
    {
        ...
        this.contentControl.Content = new CheckControl(); <- here
    }
    break;
}

FIX :您应该分配以前创建的控件:

这些变量应该是字段,因为您希望以不同的方法访问同一个实例:

private LogInControl logInControl = new LogInControl();
private CheckControl checkControl = new CheckControl();

并且开关应该是这样的:

switch (kindContentControl)
{
    case "LogIn":
    {
        ...
        this.contentControl.Content = this.logInControl;                    
    }
    break;

    case "Check":
    {
        ...
        this.contentControl.Content = this.checkControl;
    }
    break;
}

答案 1 :(得分:1)

您创建每个控件的2个实例。构造函数中的第一个,他们订阅了事件。在ChangeContentControl方法中的第二个,他们有事件订阅。

因此您可以通过将控件存储在本地变量中来重用控件

LogInControl logInControl = new LogInControl();
CheckControl checkControl = new CheckControl();

public MainWindow()
{
    InitializeComponent();

    logInControl.OnSuccessfulLogin += (senser, e) =>
    {
        ChangeContentControl("Check");
    };

    checkInControl.LogOutClick += (senser, e) =>
    {
        ChangeContentControl("LogIn");
    };
    this.contentControl.Content = logInControl;
}

public void ChangeContentControl(string kindContentControl)
{
    switch (kindContentControl)
    {
        case "LogIn":
            {
                ...
                this.contentControl.Content = logInControl ;
            }
            break;
        case "Check":
            {
                ...
                this.contentControl.Content = checkControl;
            }
            break;
    }
}

或者也可以将新实例订阅到事件。使用订阅控制是在单独的方法中创建的,以避免代码重复

public MainWindow()
{
    InitializeComponent();

    this.contentControl.Content = getLogInControl();
}

private LogInControl getLogInControl()
{
    LogInControl logInControl = new LogInControl();
    logInControl.OnSuccessfulLogin += (senser, e) =>
    {
        ChangeContentControl("Check");
    };
    return logInControl;
}

private CheckControl getCheckControl()
{
    CheckControl checkControl = new CheckControl();
    checkControl.LogOutClick += (senser, e) =>
    {
        ChangeContentControl("LogIn");
    };
    return checkControl;
}

public void ChangeContentControl(string kindContentControl)
{
    switch (kindContentControl)
    {
        case "LogIn":
            {
                ...
                this.contentControl.Content = getLogInControl();
            }
            break;
        case "Check":
            {
                ...
                this.contentControl.Content = getCheckControl();
            }
            break;
    }
}