在 WPF 中更改 DataContext/View 后保留数据
Data Retain After Changing DataContext/ Views in WPF
我是 WPF 的新手,想构建一个应用程序,它将与我的驱动程序进行串行通信,并且我可以从程序中为驱动程序设置值。
我已经成功制作了一个UI如图here . If i press Blue View as pointed by the arrow at last, the view of my window is like this. If i press the Red View Option then the display is like this
设置按钮是指向右上角的箭头(window 的关闭按钮下方),按下时我的 window 看起来像 this。
基本上我正在根据我按下的按钮更改 BIG RECTANGLE 内容(例如,单击蓝色视图时矩形为蓝色,矩形填充有红色和一个标签以及单击红色视图时更改标签的按钮)
所以现在我的问题是,在更改 BIG RECTANGLE 的内容后,我无法保留在此 BIG RECTANGLE 中设置的值].例如,当我按下设置按钮并更改 this 等设置时,我已准备好在 COM5 中进行通信,并且可以按下关闭端口的选项。现在在关闭端口之前,如果我通过按红色视图或蓝色视图更改 BIG RECTANGLE 的视图,然后在按下设置按钮之后,我就没有关闭端口的选项了,因为我之前已经打开了 com5 端口,所以当我尝试打开该端口时,它也会给我错误。
请帮我解决这个问题。我的 visual studio 解决方案资源管理器看起来像 this,我在按钮单击事件中的代码如下:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void SerialPortOnOFFButton_Clicked(object sender, RoutedEventArgs e)
{
MessageBox.Show("ON OFF Clicked");
}
private void SerialPortSettingButton_Clicked(object sender, RoutedEventArgs e)
{
DataContext = new SerialPortSettingView();
}
private void RedViewButton_Clicked(object sender, RoutedEventArgs e)
{
DataContext = new Redview();
}
private void BlueViewButton_Clicked(object sender, RoutedEventArgs e)
{
DataContext = new Blueview();
}
}
我的解决方案资源管理器看起来像 this
每次更改视图时,您都会创建一个新的 object 来将 DataContext 设置为,如果您将单个 object 保留为私有字段,则只需将 DataContext 设置为这些:
private SerialPortSettingView _serialPortSettingView;
private RedView _redView;
private BlueView _blueView;
public MainWindow()
{
_serialPortSettingView = new SerialPortSettingView();
_redView = new RedView();
_blueView = new BlueView();
InitializeComponent();
}
private void SerialPortOnOFFButton_Clicked(object sender, RoutedEventArgs e)
{
MessageBox.Show("ON OFF Clicked");
}
private void SerialPortSettingButton_Clicked(object sender, RoutedEventArgs e)
{
DataContext = _serialPortSettingView;
}
private void RedViewButton_Clicked(object sender, RoutedEventArgs e)
{
DataContext = _redview;
}
private void BlueViewButton_Clicked(object sender, RoutedEventArgs e)
{
DataContext = _blueview;
}
这样,当您在视图之间切换时,您将使用存储的版本,而当您更改值时,它们将存储在该视图中。
如果我正在执行此解决方案,我会将 ContentControl 更改为 TabControl(隐藏 headers),然后创建每个视图以及随附的 ViewModel 作为选项卡。然后,当每个点击事件被触发时,您只需设置 TabControl 的 .SelectedIndex 属性。我将创建一个 MainWindowViewModel 并在构造函数中将 MainWindow 的 DataContext 设置为此:
private MainWindowViewModel = new MainWindowViewModel();
public MainWindow()
{
DataContext = _mainWindowViewModel;
}
并将所有逻辑放在 MainWindowViewModel 中(您需要使用命令)。使用代码隐藏并不是 WPF 的本意,您可以在此处阅读所有内容,并遵循一个很好的教程 - MVVM Tutorial
我不想让事情变得过于复杂,一次性给你塞满太多信息,但如果你开始这样做会更好,希望这会有所帮助。
如果你只想关闭你的端口,你可以像这样在你的 SerialPortSettingView
class 中实现 IDisposable
接口。每次您从 SerialPortSettingView
更改 DataContext
时,您的端口将被关闭。
public class SerialPortSettingView : IDisposable
{
private FileStream _fileStream;
public SerialPortSettingView()
{
_fileStream = new FileStream("somefile.txt", FileMode.Open);
}
public void Dispose()
{
_fileStream?.Close();
}
}
我是 WPF 的新手,想构建一个应用程序,它将与我的驱动程序进行串行通信,并且我可以从程序中为驱动程序设置值。
我已经成功制作了一个UI如图here . If i press Blue View as pointed by the arrow at last, the view of my window is like this. If i press the Red View Option then the display is like this 设置按钮是指向右上角的箭头(window 的关闭按钮下方),按下时我的 window 看起来像 this。
基本上我正在根据我按下的按钮更改 BIG RECTANGLE 内容(例如,单击蓝色视图时矩形为蓝色,矩形填充有红色和一个标签以及单击红色视图时更改标签的按钮)
所以现在我的问题是,在更改 BIG RECTANGLE 的内容后,我无法保留在此 BIG RECTANGLE 中设置的值].例如,当我按下设置按钮并更改 this 等设置时,我已准备好在 COM5 中进行通信,并且可以按下关闭端口的选项。现在在关闭端口之前,如果我通过按红色视图或蓝色视图更改 BIG RECTANGLE 的视图,然后在按下设置按钮之后,我就没有关闭端口的选项了,因为我之前已经打开了 com5 端口,所以当我尝试打开该端口时,它也会给我错误。
请帮我解决这个问题。我的 visual studio 解决方案资源管理器看起来像 this,我在按钮单击事件中的代码如下:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void SerialPortOnOFFButton_Clicked(object sender, RoutedEventArgs e)
{
MessageBox.Show("ON OFF Clicked");
}
private void SerialPortSettingButton_Clicked(object sender, RoutedEventArgs e)
{
DataContext = new SerialPortSettingView();
}
private void RedViewButton_Clicked(object sender, RoutedEventArgs e)
{
DataContext = new Redview();
}
private void BlueViewButton_Clicked(object sender, RoutedEventArgs e)
{
DataContext = new Blueview();
}
}
我的解决方案资源管理器看起来像 this
每次更改视图时,您都会创建一个新的 object 来将 DataContext 设置为,如果您将单个 object 保留为私有字段,则只需将 DataContext 设置为这些:
private SerialPortSettingView _serialPortSettingView;
private RedView _redView;
private BlueView _blueView;
public MainWindow()
{
_serialPortSettingView = new SerialPortSettingView();
_redView = new RedView();
_blueView = new BlueView();
InitializeComponent();
}
private void SerialPortOnOFFButton_Clicked(object sender, RoutedEventArgs e)
{
MessageBox.Show("ON OFF Clicked");
}
private void SerialPortSettingButton_Clicked(object sender, RoutedEventArgs e)
{
DataContext = _serialPortSettingView;
}
private void RedViewButton_Clicked(object sender, RoutedEventArgs e)
{
DataContext = _redview;
}
private void BlueViewButton_Clicked(object sender, RoutedEventArgs e)
{
DataContext = _blueview;
}
这样,当您在视图之间切换时,您将使用存储的版本,而当您更改值时,它们将存储在该视图中。
如果我正在执行此解决方案,我会将 ContentControl 更改为 TabControl(隐藏 headers),然后创建每个视图以及随附的 ViewModel 作为选项卡。然后,当每个点击事件被触发时,您只需设置 TabControl 的 .SelectedIndex 属性。我将创建一个 MainWindowViewModel 并在构造函数中将 MainWindow 的 DataContext 设置为此:
private MainWindowViewModel = new MainWindowViewModel();
public MainWindow()
{
DataContext = _mainWindowViewModel;
}
并将所有逻辑放在 MainWindowViewModel 中(您需要使用命令)。使用代码隐藏并不是 WPF 的本意,您可以在此处阅读所有内容,并遵循一个很好的教程 - MVVM Tutorial
我不想让事情变得过于复杂,一次性给你塞满太多信息,但如果你开始这样做会更好,希望这会有所帮助。
如果你只想关闭你的端口,你可以像这样在你的 SerialPortSettingView
class 中实现 IDisposable
接口。每次您从 SerialPortSettingView
更改 DataContext
时,您的端口将被关闭。
public class SerialPortSettingView : IDisposable
{
private FileStream _fileStream;
public SerialPortSettingView()
{
_fileStream = new FileStream("somefile.txt", FileMode.Open);
}
public void Dispose()
{
_fileStream?.Close();
}
}