【问题标题】:XAML event handler in a nonroot object非根对象中的 XAML 事件处理程序
【发布时间】:2019-03-11 17:46:40
【问题描述】:

想象一下以下 XAML:

<Page
    x:Class="MyProject.MainPage"
    xmlns:local="using:MyProject">

   <local:MyStackPanel>
       <Button Content="Go" Click="OnGo"/>
   </local:MyStackPanel>
</Page>

XAML 假定 OnGo 是页面类中的一个方法。我可以以某种方式以声明方式告诉它OnGo 位于MyStackPanel 中吗?

我知道我可以在页面加载后以编程方式分配事件处理程序。我想知道是否可以通过纯粹的 XAML 方式实现。 “不”是一个可以接受的答案:)

【问题讨论】:

    标签: xaml uwp-xaml


    【解决方案1】:

    根据您的要求,您可以将 MyStackPanel DataContext 与自身绑定。然后在MyStackPanel类中创建用于绑定按钮命令的BtnClickCommand,如下所示。

    public class MyStackPanel : StackPanel
    {
        public MyStackPanel()
        {
    
        }
    
        public ICommand BtnClickCommand
        {
            get
            {
                return new RelayCommand(() =>
                {
    
    
                });
            }
        }
    
    }
    public class RelayCommand : ICommand
    {
        private readonly Action _execute;
        private readonly Func<bool> _canExecute;
        /// <summary>
        /// Raised when RaiseCanExecuteChanged is called.
        /// </summary>
        public event EventHandler CanExecuteChanged;
        /// <summary>
        /// Creates a new command that can always execute.
        /// </summary>
        /// <param name="execute">The execution logic.</param>
        public RelayCommand(Action execute)
            : this(execute, null)
        {
        }
        /// <summary>
        /// Creates a new command.
        /// </summary>
        /// <param name="execute">The execution logic.</param>
        /// <param name="canExecute">The execution status logic.</param>
        public RelayCommand(Action execute, Func<bool> canExecute)
        {
            if (execute == null)
                throw new ArgumentNullException("execute");
            _execute = execute;
            _canExecute = canExecute;
        }
        /// <summary>
        /// Determines whether this RelayCommand can execute in its current state.
        /// </summary>
        /// <param name="parameter">
        /// Data used by the command. If the command does not require data to be passed,
        /// this object can be set to null.
        /// </param>
        /// <returns>true if this command can be executed; otherwise, false.</returns>
        public bool CanExecute(object parameter)
        {
            return _canExecute == null ? true : _canExecute();
        }
        /// <summary>
        /// Executes the RelayCommand on the current command target.
        /// </summary>
        /// <param name="parameter">
        /// Data used by the command. If the command does not require data to be passed,
        /// this object can be set to null.
        /// </param>
        public void Execute(object parameter)
        {
            _execute();
        }
        /// <summary>
        /// Method used to raise the CanExecuteChanged event
        /// to indicate that the return value of the CanExecute
        /// method has changed.
        /// </summary>
        public void RaiseCanExecuteChanged()
        {
            var handler = CanExecuteChanged;
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }
        }
    }
    

    用法

    <local:MyStackPanel DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}">
        <Button Command="{Binding BtnClickCommand}" Content="ClickMe" />
    </local:MyStackPanel>
    

    【讨论】:

    • 谢谢。不过,几乎没有声明性。
    • @SevaAlekseyev 这个答案不符合要求吗?
    • 没有任何要求,只是希望 XAML 比我知道的更灵活 :) 显然不是。
    • @SevaAlekseyev,好吧,Xaml 不灵活。它不能做你想做的事。欢迎您在UserVoice发帖。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 2019-05-01
    • 1970-01-01
    • 2018-07-13
    • 1970-01-01
    • 2018-02-13
    • 1970-01-01
    相关资源
    最近更新 更多