我有一个用户控件,其中包含CheckBox
,Button
和CommandBinding
。如果选中CheckBox
,则会启用Button
。 MainWindow
使用UserControl
。当按下主窗口中的Button
时,会从用户界面中移除UserControl
,并且会调用GC.Collect()
,但仍会运行CanExecute
方法。
我发现如果我单击主窗口中的按钮两次,CanExecute
将不再运行。我似乎没有在合适的时间致电GC.Collect()
。
我想知道调用GC清理未使用的用户控件的好时机,因此不会调用CanExecute
。
XAML
<UserControl x:Class="WpfApplication1.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<RoutedUICommand x:Key="okCommand" Text="OK"/>
</UserControl.Resources>
<UserControl.CommandBindings>
<CommandBinding Command="{StaticResource okCommand}" CanExecute="CommandBinding_CanExecute_1"/>
</UserControl.CommandBindings>
<StackPanel>
<CheckBox Name="checkBox" Content="CheckBox"/>
<Button Command="{StaticResource okCommand}" Content="{Binding Path=Text, Source={StaticResource okCommand}}"/>
</StackPanel>
</UserControl>
Code behind
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
private void CommandBinding_CanExecute_1(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = checkBox.IsChecked.GetValueOrDefault(false);
System.Media.SystemSounds.Beep.Play();
}
}
MainWindow
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Loaded="Window_Loaded_1">
<StackPanel>
<Border Name="container"/>
<Button Content="Set Null" Click="Button_Click_1"/>
</StackPanel>
</Window>
Code behind
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
container.Child = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
private void Window_Loaded_1(object sender, RoutedEventArgs e)
{
UserControl1 uc = new UserControl1();
container.Child = uc;
}
}
答案 0 :(得分:0)
使用grid作为容器和Container.Clear()方法并忘记GC。
答案 1 :(得分:0)
我找到另一种解决方案。这是在卸载时调用UserControl1中的CommandBindings.Clear()
。
我认为这是一种巧妙的方式,因为UserControl1的调用者不会处理UserControl1的清理工作。