【发布时间】:2015-10-22 19:49:41
【问题描述】:
我有一个 wpf 应用程序,它有一个主窗口和菜单。这个主窗口有一个面板,在点击菜单项时,我创建了一个用户控件的实例并使用该控件加载面板。
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="" MinHeight="750" Height="Auto" MinWidth="1100" Width="Auto" WindowState="Maximized" ScrollViewer.VerticalScrollBarVisibility="Auto"
Loaded ="MainWindow_OnLoaded" Closing="Window_Closing">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility ="Auto" SizeChanged="ScrollViewer_SizeChanged">
<Grid Width="Auto">
<Grid.RowDefinitions>
<RowDefinition Height="38"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Height="38" Width="Auto" Background="#09527B">
<Grid Margin="0,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition Width="70"></ColumnDefinition>
</Grid.ColumnDefinitions>
</Grid>
</StackPanel>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="189"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<StackPanel>
<Expander Name="test" Header="Admin" Foreground="White" Margin="0,10,0,0">
<StackPanel Margin="20,0,0,0">
<Expander Header="Data" Foreground="White">
<StackPanel>
<TextBlock Text="Add/Edit UC1" Foreground="White" Margin="30,5,0,0" MouseDown="OpenUC1_MouseDown" MouseEnter="TextBlock_MouseEnter" MouseLeave="TextBlock_MouseLeave"/>
<TextBlock Text="Add/Edit UC2" Name="tbxBuild" Foreground="White" Margin="30,5,0,0" MouseDown="OpenUC2_MouseDown" MouseEnter="TextBlock_MouseEnter" MouseLeave="TextBlock_MouseLeave"/>
</StackPanel>
</Expander>
</StackPanel>
</Grid>
<StackPanel Grid.Column="1">
<Grid Name="pnlMain" Height ="Auto" VerticalAlignment="Top" HorizontalAlignment="Left">
</Grid>
</StackPanel>
</Grid>
</Grid>
</ScrollViewer>
</Window>
MainWindow.cs
private void OpenUC1_MouseDown(object sender, MouseButtonEventArgs e)
{
for (int i = 0; i < pnlMain.Children.Count; i++ )
{
pnlMain.Children.Remove(pnlMain.Children[i]);
}
using (UC2 _uc2= new UC2())
{
pnlMain.Children.Add(_uc2);
}
}
private void OpenUC2_MouseDown(object sender, MouseButtonEventArgs e)
{
for (int i = 0; i < pnlMain.Children.Count; i++ )
{
pnlMain.Children.Remove(pnlMain.Children[i]);
}
using (UC1 _uc1= new UC1())
{
pnlMain.Children.Add(_uc1);
}
}
我的问题是,当我从主面板中移除控件(UC1)时,该控件何时会被释放? 用户控件(UC1 和 UC2)都有相同的视图模型附加到其数据上下文。因此,我发现即使从面板中删除了已删除的用户控件(UC1)中的某些方法,也会调用这些方法。原因是,当创建 UC2 的新实例时,数据模型中会发生一些变化,这实际上调用了 UC1 中的依赖方法。 但如果 UC1 已被处置,这将不会发生。如何确保在创建 UC2 实例之前释放 UC1?
public UC1()
{
InitializeComponent();
this.DataContext = App.ViewModel.TestViewModel;
}
private void UC1_Unloaded(object sender, RoutedEventArgs e)
{
this.DataContext = null;
}
public UC2()
{
InitializeComponent();
this.DataContext = App.ViewModel.TestViewModel;
}
private void UC2_Unloaded(object sender, RoutedEventArgs e)
{
this.DataContext = null;
}
从面板中移除控件时,不会立即调用 unloaded 方法。
【问题讨论】:
-
这个问题不清楚。 “Disposed”在 .NET/C# 的上下文中具有非常特殊的含义:“调用对象的
IDisposable.Dispose()方法”。您似乎没有在此处处理IDisposable,因此使用“处置”一词是不正确且具有误导性的。一般来说,Unloaded事件应该引发“当从加载元素的元素树中删除元素时”,正如 MSDN 所说。但是如果没有可靠地重现问题的a good, minimal, complete code example,很难说为什么它不适合你