0

我有一个用户控件,它有一个CheckBox、一个Button和一个CommandBinding。如果CheckBox选中 ,Button则启用 。MainWindow使用UserControl. _ Button按下主窗口中的 时,会UserControl从 UI 中删除并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;
    }
}
4

2 回答 2

0

使用网格作为容器和 Container.Clear() 方法,忘记 GC。

于 2013-02-02T16:49:25.917 回答
0

我找到了另一个解决方案。也就是CommandBindings.Clear()卸载时调用UserControl1。

我相信这是一种巧妙的方式,因为 UserControl1 的调用者不负责 UserControl1 的清理工作。

于 2013-02-06T01:00:19.650 回答