何时清理命令绑定控件?

时间:2013-02-02 11:19:51

标签: c# wpf button user-controls commandbinding

我有一个用户控件,其中包含CheckBoxButtonCommandBinding。如果选中CheckBox,则会启用ButtonMainWindow使用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;
    }
}

2 个答案:

答案 0 :(得分:0)

使用grid作为容器和Container.Clear()方法并忘记GC。

答案 1 :(得分:0)

我找到另一种解决方案。这是在卸载时调用UserControl1中的CommandBindings.Clear()

我认为这是一种巧妙的方式,因为UserControl1的调用者不会处理UserControl1的清理工作。