Как передать кнопку как CommandParameter из XAML на странице Xamarin.Forms?

Я хотел бы передать Xamarin.Forms.Button в своем собственном Command в качестве CommandParameter моей ViewModel. Я знаю, как добиться этого из кода, например. ...

XAML (большинство свойств пропущено для краткости)

<Button x:Name="myButton"
    Text="My Button"
    Command="{Binding ButtonClickCommand}"/>

XAML.cs

public partial class MyTestPage
{
    public MyTestPage()
    {
        InitializeComponent();

        myButton.CommandParameter = myButton;
    }
}

ViewModel

public class MyViewModel : ViewModelBase
{
    public MyViewModel()
    {
        ButtonClickCommand = new Command(
            (parameter) =>
            {
                var view = parameter as Xamarin.Forms.Button;
                if (view != null)
                {
                    // Do Stuff
                }
            });
    }

    public ICommand ButtonClickCommand { get; private set; }
}

... НО можно ли объявить CommandParameter в самом XAML? Или, другими словами, каков синтаксис привязки для установки параметра самой кнопки?

<Button x:Name="myButton"
        Text="My Button"
        Command="{Binding ButtonClickCommand}"
        CommandParameter="{[WHAT WOULD GO HERE]}"/>

кстати, я уже пробовал CommandParameter="{Binding RelativeSource={RelativeSource Self}}", и это не сработало.

Спасибо,


person Gavin Sutherland    schedule 18.09.2014    source источник
comment
Зачем вам нужна кнопка на вашей виртуальной машине?   -  person Alex Anderson    schedule 18.09.2014
comment
Привет, @AlexAnderson. Да, мне это тоже не очень нравится. Мы вводим Xamarin.Forms в существующий проект Xamarin iOS. Просто экспериментирую со способами получить собственный UIPopoverController для отображения на странице Xamarin.Form. Формы не поддерживают всплывающие окна, поэтому сейчас просто ищу способы обойти это, и одно из препятствий заключается в том, что мне нужно знать, какой UIElement отображать всплывающее окно ... следовательно, я передаю кнопку. Как я уже сказал ... вроде как хоккей. Я попробую ваше предложение ниже. Спасибо   -  person Gavin Sutherland    schedule 18.09.2014
comment
Что касается всплывающих окон, проверьте реализацию ContentPage.DisplayActionSheet(...) - если листа действий недостаточно, вы можете перепроектировать код, который его показывает. И для получения ссылки на кнопку все равно потребуется найти ссылку на UIButton. Вам будет лучше с настраиваемым рендерером   -  person Sten Petrov    schedule 18.09.2014
comment
Привет @StenPetrov. Проблема с созданием настраиваемого средства визуализации для всплывающего окна заключается в том, что UIPopoverController является NSObject, а не объектом UIView.   -  person Gavin Sutherland    schedule 18.09.2014


Ответы (4)


Xamarin.Forms имеет расширение справочной разметки, которое делает именно это:

<Button x:Name="myButton"
    Text="My Button"
    Command="{Binding ButtonClickCommand}"
    CommandParameter="{x:Reference myButton}"/>

Хотя это первый раз, когда я вижу эту потребность, и вы, вероятно, сможете лучше отделить ваши представления от ваших ViewModels и решить эту проблему, используя более чистый шаблон или не разделяя команду между кнопками.

person Stephane Delcroix    schedule 18.09.2014
comment
Привет, @StephaneDelcroix. К сожалению, это тоже не сработало .. Исключение было выброшено целью вызова. - person Gavin Sutherland; 18.09.2014
comment
не могли бы вы поделиться трассировкой стека? вы используете xaml 2009 xmlns? вы используете последнюю (1.2.2 или 1.2.3-pre2) версию XF? - person Stephane Delcroix; 18.09.2014
comment
Мне очень жаль, @GavinSutherland, но я только что протестировал это на 1.2.3-pre-2, и он работает, как ожидалось. - person Stephane Delcroix; 19.09.2014
comment
Привет, @StephaneDelcroix. Я проверю пространство имен и версии xf. Если они обновлены, я, возможно, попробую его в пустом проекте. Спасибо за обновления - person Gavin Sutherland; 19.09.2014
comment
Привет, @StephaneDelcroix. Я использую v1.2.2, и у меня объявлены следующие пространства имен: xmlns="http://xamarin.com/schemas/2014/forms" и xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml". Это правильно? - person Gavin Sutherland; 21.09.2014
comment
@GavinSutherland: да, все в порядке. С 1.2.2 не пробовал. - person Stephane Delcroix; 21.09.2014
comment
Как это будет выглядеть на C #? И как я могу ссылаться на кнопку внутри самой команды? - person jbyrd; 07.04.2016
comment
Когда я пытаюсь сделать это в коде, я получаю сообщение об ошибке. Указанный приведение недопустим, что напрямую связано со строкой CommandParameterProperty. - person jbyrd; 07.04.2016
comment
Это именно то, что я искал, спасибо. Хотя это несколько разрушает разделение пользовательского интерфейса и кода, я не мог придумать лучшего решения моей проблемы: я хочу иметь возможность переключаться между полями ввода (Xamarin.Forms.Entry) после того, как пользователь нажимает клавишу «Return». key с помощью этого решения: stackoverflow.com/a/37448069/5400351 @jbyrd: Вот как выглядит мой код ViewModel: this.FocusVisualElementCommand = new Command<VisualElement>(visualElement => visualElement?.Focus()); - person Sam del Rö; 26.06.2017

 <Button x:Name="myButton"
        Text="My Button"
        Command="{Binding ButtonClickCommand}"
        CommandParameter="{x:Reference myButton}"/>

В вашей ViewModel

public YourViewModel()
{
    ButtonClickCommand= new Command(ButtonClicked);
}

private async void ButtonClicked(object sender)
{
    var view = sender as Xamarin.Forms.Button;
}
person Luiz Fernando Corrêa Leite    schedule 10.05.2018
comment
Не работает с Prism, запрашивает параметр при передаче команды. - person R15; 10.05.2019

<Button x:Name="myButton"
    Text="My Button"
    Command="{Binding ButtonClickCommand}"
    CommandParameter={Binding RelativeSource=
                               {RelativeSource
                                Mode=FindAncestor,
                                AncestorType={x:Type Button}}/>

Должно сработать, но я все еще не понимаю, зачем вам кнопка? Задача MVVM - разделить данные и пользовательский интерфейс. все, что вам нужно сделать с кнопкой, можно сделать через DataBindings.

Если вышеперечисленное не работает, попробуйте дать кнопке x: Key и CommandParamter = {StaticResource 'x: Key'}.

person Alex Anderson    schedule 18.09.2014
comment
У привязок Xamarin.Forms нет ни свойства RelativeSource, ни расширения разметки RelativeSource. - person Stephane Delcroix; 18.09.2014
comment
Привет, @AlexAnderson ... да, боюсь, ни одно из этих предложений не сработало. - person Gavin Sutherland; 18.09.2014
comment
@Alex Что, если вы хотите изменить кнопку VisualState для вызывающего абонента, я думаю, нам нужно это сделать. - person Sumit Gupta; 06.03.2021

Простой способ:

В XAML:

 <Button Text="BUTTON-TEST"
            Clicked="Avaliar"
            CommandParameter="like"/>

In C#:

private void Avaliar(object sender, EventArgs e)
{
     Console.WriteLine(((Button)sender).CommandParameter);
}
person Igor Gregori    schedule 22.04.2020
comment
Не следует MVVM, и я предполагаю, что OP использует виртуальную машину. - person Sparers; 09.02.2021