#xaml #uwp-xaml
#xaml #uwp-xaml
Вопрос:
Представьте следующий XAML:
<Page
x:Class="MyProject.MainPage"
xmlns:local="using:MyProject">
<local:MyStackPanel>
<Button Content="Go" Click="OnGo"/>
</local:MyStackPanel>
</Page>
XAML предполагает, что OnGo
это метод в классе page. Могу ли я как-то декларативно указать, что OnGo
находится в MyStackPanel
вместо этого?
Я знаю, что могу назначить обработчик событий программно после загрузки страницы. Мне интересно, возможно ли это чисто средствами XAML. «Нет» — приемлемый ответ 🙂
Ответ №1:
По вашему требованию вы могли бы связать MyStackPanel DataContext
с самим собой. Затем создайте BtnClickCommand
тот, который использовался для привязки команды button в MyStackPanel
классе, как показано ниже.
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>
Комментарии:
1. Спасибо. Хотя вряд ли декларативный.
2. @SevaAlekseyev Этот ответ не соответствует требованиям?
3. Нет никаких требований, просто надеюсь, что XAML был более гибким, чем я знал 🙂 По-видимому, нет.
4. @SevaAlekseyev, Ладно, Xaml был негибким. он не может делать то, что вы хотите. Вы можете размещать сообщения на пользовательском голосе .