gpt4 book ai didi

wpf - ui 何时与命令分离?

转载 作者:行者123 更新时间:2023-12-02 07:02:56 25 4
gpt4 key购买 nike

这个问题我真是摸不着头脑。我有一个打开对话框的主窗口。对话框关闭后,对话框中绑定(bind)的命令的 CanExecute 方法仍在执行。这在我的应用程序中造成了一些严重的问题。

示例:

主窗口有一个带有单击处理程序的按钮。这是点击事件处理程序:

    private void Button_Click(object sender, RoutedEventArgs e)
{
DialogWindow window = new DialogWindow();
window.ShowDialog();
}

在对话框中,我将项目控件绑定(bind)到对话框窗口中的静态资源,列表中的每个项目都有一个命令:

<Window.Resources>

<Collections:ArrayList x:Key="itemsSource">
<local:ItemViewModel Description="A"></local:ItemViewModel>
<local:ItemViewModel Description="B"></local:ItemViewModel>
<local:ItemViewModel Description="C"></local:ItemViewModel>
</Collections:ArrayList>

<DataTemplate DataType="{x:Type local:ItemViewModel}">
<Button Grid.Column="1" Command="{Binding Path=CommandClickMe}" Content="{Binding Path=Description}" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}">
</Button>
</DataTemplate>

</Window.Resources>

<Grid>
<ToolBar ItemsSource="{StaticResource itemsSource}"></ToolBar>
</Grid>

这是 View 模型:

public class ItemViewModel
{
private RelayWpfCommand<object> _commandClickMe;

public RelayWpfCommand<object> CommandClickMe
{
get
{
if (_commandClickMe == null)
_commandClickMe = new RelayWpfCommand<object>(obj => System.Console.Out.WriteLine("Hei mom"), obj => CanClickMe());

return _commandClickMe;
}
}

private bool CanClickMe()
{
return true;
}

public string Description { get; set; }

这是 DelegateCommand 实现:

public class RelayWpfCommand<T> : ICommand
{
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}

private readonly Predicate<T> _canExecute;
private readonly Action<T> _execute;

public RelayWpfCommand(Action<T> execute, Predicate<T> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}

/// <summary>
/// Forces a notification that the CanExecute state has changed
/// </summary>
public void RaiseCanExecuteChanged()
{
CommandManager.InvalidateRequerySuggested();
}

public bool CanExecute(T parameter)
{
return _canExecute(parameter);
}

public void Execute(T parameter)
{
_execute(parameter);
}

bool ICommand.CanExecute(object parameter)
{
if (!IsParameterValidType(parameter))
return false;

return CanExecute((T)parameter);
}

void ICommand.Execute(object parameter)
{
if (!IsParameterValidType(parameter))
throw new ArgumentException(string.Format("Parameter must be of type {0}", typeof(T)));

Execute((T)parameter);
}

private static bool IsParameterValidType(object parameter)
{
if (parameter != null && !typeof(T).IsAssignableFrom(parameter.GetType()))
return false;

return true;
}
}

现在,如果我关闭对话框窗口并在 View 模型上的 CanExecute(我使用带有弱事件订阅的 Prism DelegateCommand)方法中设置断点,我注意到尽管对话框已关闭,它仍然会触发。到底为什么对话框中的按钮和 ViewModel 上的命令之间的绑定(bind)仍然有效?

我正在通过关闭窗口并稍后在 View 模型中的“CanClickMe”方法中设置断点来检查它是否正在执行。它会执行一段时间,然后突然停止(可能是由于GC)。这种非确定性行为会导致问题,因为在实际应用程序中, View 模型可能已经被释放。

最佳答案

您可以使用 Wea​​kEvent 模式来缓解此问题。请引用以下 Stackoverflow 问题:Is Josh Smith's implementation of the RelayCommand flawed?

关于wpf - ui 何时与命令分离?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4095037/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com