【发布时间】:2010-12-05 07:36:52
【问题描述】:
我有一个使用 Window.Show() 显示的 WPF 窗口。 当我单击 X 时,表单关闭。 但它仍在内存中,GC 永远不会来清理它。 我也没有任何参考/句柄。
有谁知道是什么导致它留在内存中?
谢谢!
更新: 我正在使用以下代码来创建窗口:
Public Sub OpenPageWindow(ByVal nick As String)
Dim found As Boolean
For Each pw As PageWindow In Application.Current.Windows.OfType(Of PageWindow)()
If Not pw.Tag Is Nothing Then
If pw.Tag.ToString() = nick Then
If pw.IsVisible = False Then
pw.Show()
End If
Exit Sub
End If
End If
Next
If found = False Then
Dim p As New PageWindow With {.Name = "pw" & nick, .Tag = nick, _
.Title = "Chatting with " & nick, .ShowActivated = False}
p.Show()
End If
End Sub
以及窗口本身的以下代码隐藏:
Public Class PageWindow
Implements System.IDisposable
Public UserPressedExit As Boolean
Dim MainWin As MainWindow
Private _IsBuddy As Boolean
Private _IsBlocked As Boolean
Private _IsOnline As Boolean
Public Property FirstOpen As Boolean
Public Property IsOnline As Boolean
Get
Return _IsOnline
End Get
Set(ByVal value As Boolean)
If _IsOnline <> value Then
_IsOnline = value
End If
End Set
End Property
Public Property IsBuddy As Boolean
Get
Return _IsBuddy
End Get
Set(ByVal value As Boolean)
If _IsBuddy <> value Then
_IsBuddy = value
'If value Then
' btnAddBuddy.IsEnabled = False
' iDeleteBuddy.IsEnabled = True
'Else
' btnAddBuddy.IsEnabled = True
' iDeleteBuddy.IsEnabled = False
'End If
End If
End Set
End Property
Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Try
MainWin = CType(Application.Current.Windows(0), MainWindow)
Catch ex As Exception
txtChat.AppendText("ERROR: " & ex.Message.ToString() & Environment.NewLine)
End Try
End Sub
Private Sub Window_Closed(ByVal sender As System.Object, ByVal e As System.EventArgs)
Me.Dispose()
End Sub
Private Sub txtTitle_PreviewMouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseButtonEventArgs)
Me.DragMove()
End Sub
Private Sub pbMin_PreviewMouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseButtonEventArgs)
WindowState = Windows.WindowState.Minimized
End Sub
Private Sub pbClose_PreviewMouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseButtonEventArgs)
UserPressedExit = True
txtChat.Clear()
Me.Close()
End Sub
Private Sub txtSend_KeyUp(ByVal sender As System.Object, ByVal e As System.Windows.Input.KeyEventArgs)
If e.Key = Key.Enter Then
btnSend_Click(Nothing, Nothing)
End If
End Sub
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
If String.IsNullOrWhiteSpace(txtSend.Text) Then
MessageBox.Show("Empty Message.")
txtSend.Text = ""
Else
Send(txtSend.Text)
txtSend.Text = ""
End If
End Sub
Public Sub Page(ByVal message As String)
If String.IsNullOrEmpty(message) = False Then
If MainWin.Settings.ShowPageTimestamp Then
txtChat.AppendText(Me.Tag.ToString() & " (" & Format(Date.Now, "HH:mm:ss") & "): " & message & Environment.NewLine)
Else
txtChat.AppendText(Me.Tag.ToString() & ": " & message & Environment.NewLine)
End If
If Me.IsFocused = False Then
End If
End If
End Sub
Private Sub Send(ByVal text As String)
'work on 389 event
MainWin.Send("PAGE " + Me.Tag.ToString + " " + text)
If MainWin.Settings.ShowPageTimestamp Then
txtChat.AppendText(MainWin.Settings.Nick & ": " & text & Environment.NewLine)
Else
txtChat.AppendText(MainWin.Settings.Nick & " (" & Format(Date.Now, "HH:mm:ss") & "): " & text & Environment.NewLine)
End If
End Sub
#Region "IDisposable Support"
Private disposed As Boolean ' To detect redundant calls
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposed Then
If disposing Then
'dispose managed state (managed objects).
RemoveHandler Me.Loaded, AddressOf Window_Loaded
RemoveHandler txtTitle.PreviewMouseDown, AddressOf txtTitle_PreviewMouseDown
RemoveHandler pbMin.PreviewMouseUp, AddressOf pbMin_PreviewMouseUp
RemoveHandler pbClose.PreviewMouseUp, AddressOf pbClose_PreviewMouseUp
RemoveHandler txtSend.KeyUp, AddressOf txtSend_KeyUp
RemoveHandler btnSend.Click, AddressOf btnSend_Click
RemoveHandler Me.Closed, AddressOf Window_Closed
BindingOperations.ClearBinding(txtTitle, TextBlock.TextProperty)
Me.Icon = Nothing
ibBackground = Nothing
'iDeleteBuddy = Nothing
'btnAddBuddy = Nothing
'iBlockUser = Nothing
pbMin = Nothing
pbClose = Nothing
MainWin = Nothing
Me.Resources.Clear()
GC.Collect()
End If
End If
Me.disposed = True
End Sub
Protected Overrides Sub Finalize()
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(False)
MyBase.Finalize()
End Sub
#End Region
End Class
然后是 XAML 的以下代码:
<Window x:Class="PageWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="PageWindow" Height="300" Width="400"
Icon="Images\R2.ico" WindowStyle="None" ResizeMode="NoResize"
WindowStartupLocation="Manual" Loaded="Window_Loaded"
BorderThickness="2" BorderBrush="#FFAE28"
Closed="Window_Closed">
<Window.Resources>
<Style x:Key="sRenegadeButton" TargetType="Button">
<Setter Property="FontFamily" Value="Franklin Gothic Medium" />
<Setter Property="FontSize" Value="12px" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="#FFAE28" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="Border" BorderBrush="#FFAE28" BorderThickness="1" CornerRadius="3"
Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Border Name="innerborder" BorderBrush="#FFAE28" BorderThickness="1" CornerRadius="3"
Background="{TemplateBinding Background}" SnapsToDevicePixels="True" Margin="1">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Name="content" />
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="BorderBrush" Value="#FFD528" />
<Setter TargetName="innerborder" Property="BorderBrush" Value="#FFD528" />
<Setter Property="Background" Value="#28FFAE28" />
<Setter Property="Foreground" Value="#FFD528" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#28FFAE28" />
<Setter TargetName="content" Property="RenderTransform" >
<Setter.Value>
<TranslateTransform Y="1.0" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="BorderBrush" Value="#80E6A023" />
<Setter TargetName="innerborder" Property="BorderBrush" Value="#80E6A023" />
<Setter Property="Foreground" Value="#8CFFD528" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="sRenegadeTextBox" TargetType="TextBox">
<Setter Property="FontFamily" Value="Franklin Gothic Medium" />
<Setter Property="FontSize" Value="12px" />
<Setter Property="Foreground" Value="#FFD528" />
<Setter Property="Background" Value="#28FFAE28" />
<Setter Property="BorderBrush" Value="#FFAE28" />
<Setter Property="CaretBrush" Value="#FFAE28" />
<Setter Property="SelectionBrush" Value="#FFD528" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border Name="Bd" BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<ScrollViewer Name="PART_ContentHost" Background="{TemplateBinding Background}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="#8CFFD528" />
<Setter Property="Background" Value="#1EFFAE28" />
<Setter Property="BorderBrush" Value="#80E6A023" />
<Setter TargetName="PART_ContentHost" Property="Background" Value="#1EFFAE28"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="21" />
<RowDefinition Height="32" />
<RowDefinition Height="*" />
<RowDefinition Height="27" />
</Grid.RowDefinitions>
<Grid.Background>
<ImageBrush x:Name="ibBackground" ImageSource="Images\page_back.gif" />
</Grid.Background>
<Border Grid.Row="0" BorderBrush="#FFAE28" BorderThickness="0,0,0,2"
SnapsToDevicePixels="True" />
<Grid Name="gTitleBar" Grid.Row="0" Background="#32FFAE28">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="32" />
</Grid.ColumnDefinitions>
<TextBlock Name="txtTitle" Grid.Column="0" Text="{Binding Title,RelativeSource={RelativeSource FindAncestor,AncestorType=Window}}"
HorizontalAlignment="Stretch" VerticalAlignment="Center"
TextAlignment="Left" Margin="4,0,1,0"
PreviewMouseDown="txtTitle_PreviewMouseDown"
Foreground="#FED528" FontFamily="Franklin Gothic Medium" />
<Image Name="pbMin" Grid.Column="1" Width="28" Height="15"
HorizontalAlignment="Center" VerticalAlignment="Center"
PreviewMouseUp="pbMin_PreviewMouseUp" Stretch="None">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="Images\min.png" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Source" Value="Images\min_o.png" />
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<Image Name="pbClose" Grid.Column="2" Width="28" Height="15"
HorizontalAlignment="Left" VerticalAlignment="Center"
PreviewMouseUp="pbClose_PreviewMouseUp" Stretch="None">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="Images\close2.png" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Source" Value="Images\close2_o.png" />
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="25" />
<ColumnDefinition Width="25" />
<ColumnDefinition Width="25" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!--<Button Name="btnAddBuddy" Grid.Column="1" Margin="0,2,0,0">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Border Name="Border" BorderBrush="Transparent" BorderThickness="1" CornerRadius="3"
Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
</Border>
<Image Name="iAddBuddy" Margin="1" Source="Images\Add Buddy 32x36.png" />
<Image Name="iAddBuddyDissabled" Margin="1" Source="Images\Add Buddy 32x36.png" Visibility="Hidden" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="BorderBrush" Value="#FFD528" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#FFD528" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="BorderBrush" Value="Transparent" />
<Setter TargetName="iAddBuddy" Property="Visibility" Value="Hidden" />
<Setter TargetName="iAddBuddyDissabled" Property="Visibility" Value="Visible" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
<Border Name="bDeleteBuddyBorder" Grid.Column="2" BorderThickness="1"
SnapsToDevicePixels="True" Margin="0,2,0,0">
<Image Name="iDeleteBuddy" Margin="1" IsEnabled="True"
Source="Images\Delete 32x32.png">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Source" Value="Images\Delete Disabled 32x32.png" />
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<Border.Style>
<Style TargetType="Border">
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Background" Value="Transparent" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="#FFD528" />
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
<Border Name="bBlockUserBorder" Grid.Column="3" BorderThickness="1"
SnapsToDevicePixels="True" Margin="0,2,0,0">
<Image Name="iBlockUser" Margin="1" IsEnabled="True"
Source="Images\Block Buddy 32x36.png">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Source" Value="Images\Block Buddy Dissabled 32x36.png" />
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<Border.Style>
<Style TargetType="Border">
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Background" Value="Transparent" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="#FFD528" />
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>-->
</Grid>
<TextBox Name="txtChat" Grid.Row="2" Margin="4,2,4,2"
Style="{StaticResource sRenegadeTextBox}" UndoLimit="0" />
<Grid Grid.Row="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="45" />
</Grid.ColumnDefinitions>
<TextBox Name="txtSend" Grid.Column="0" MaxLength="495"
Height="22" Margin="4,1,2,4" VerticalContentAlignment="Center"
Style="{StaticResource sRenegadeTextBox}" UndoLimit="0"
KeyUp="txtSend_KeyUp" />
<Button Name="btnSend" Content="Send" Grid.Column="1"
Style="{StaticResource sRenegadeButton}"
Height="22" Width="40" Margin="0,1,4,4" Click="btnSend_Click" />
</Grid>
</Grid>
</Window>
基本上,即使我创建一个带有主网格背景图像的空 WPF 窗口和 2 个打开和关闭事件处理程序,它仍然保留在内存中,但是当所有“空 wpf”窗口都关闭时,内存只会减少一点。只是一点点。为什么不完全丢弃简单的窗口?我什至尝试过实现上面编码的已处置功能。
【问题讨论】:
-
你怎么知道它还在记忆中?
-
我单击一个执行 windowname.show() 的按钮,然后在窗口中单击 X 按钮。并且任务管理器中的内存永远不会改变。它对以后制作的每个窗口都执行此操作。
标签: wpf vb.net wpf-controls window dispose