在 WPF window 中动态更改一些 UserControl 中的内容
Changing content dynamically in WPF window from a few UserControl
我有两个用户控件,例如 LogInControl
和 CheckControl
。最初,window 包含 LogInControl
并且登录成功后 window 更改: window 包含 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"按钮,在window中点击这个按钮应该会出现'LogInControl'内容。但它并没有发生。
代码来自CheckControl
public event EventHandler LogOutClick;
private void logOutButton_Click(object sender, RoutedEventArgs e)
{
LogOutClick?.Invoke(this, e);
}
当您使用 CheckInControl
转换到 window 时,LogOutClick
事件跟踪停止(LogOutClick 变为空)。
我不明白为什么会这样。请帮助我。
您面临的问题是,当您切换控件时,您正在创建新的控件。新的没有注册事件。所以你正在覆盖之前用注册的事件创建的。
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;
}
您为每个控件创建了 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;
}
}
我有两个用户控件,例如 LogInControl
和 CheckControl
。最初,window 包含 LogInControl
并且登录成功后 window 更改: window 包含 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"按钮,在window中点击这个按钮应该会出现'LogInControl'内容。但它并没有发生。
代码来自CheckControl
public event EventHandler LogOutClick;
private void logOutButton_Click(object sender, RoutedEventArgs e)
{
LogOutClick?.Invoke(this, e);
}
当您使用 CheckInControl
转换到 window 时,LogOutClick
事件跟踪停止(LogOutClick 变为空)。
我不明白为什么会这样。请帮助我。
您面临的问题是,当您切换控件时,您正在创建新的控件。新的没有注册事件。所以你正在覆盖之前用注册的事件创建的。
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;
}
您为每个控件创建了 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;
}
}