在代码中设置Xamarin.Forms绑定的CommandParameter

5

我正试图在代码中为TapGestureRecognizer设置绑定,但我无法弄清如何正确进行。有效的xaml看起来像这样...

<Grid>
    <Grid.GestureRecognizers>
        <TapGestureRecognizer Command="{Binding LaunchLocationDetailsCommand}" 
                              CommandParameter="{Binding}" />
    </Grid.GestureRecognizers>
</Grid>

在C#中,它看起来像这样...
var gridTap = new TapGestureRecognizer();

gridTap.SetBinding(TapGestureRecognizer.CommandProperty, 
                   new Binding("LaunchLocationDetailsCommand"));

gridTap.SetBinding(TapGestureRecognizer.CommandParameterProperty, 
                   new Binding(/* here's where I'm confused */));

var grid = new Grid();
grid.GestureRecognizers.Add(gridTap);

我的疑惑在于CommandParameterProperty的绑定。在xaml中,它只需使用{Binding}而不需要其他参数。那么在代码中怎么做呢?传递new Binding()或者this.BindingContext似乎行不通。

2个回答

4
CommandProperty绑定与你之前做的相同。
由于您没有传递要使用的某个属性的路径,因此您的CommandParameterProperty不能只创建空的Binding,否则会抛出异常。
为了解决这个问题,您需要指定Source属性,正如Adam所指出的那样。
请注意,如果您尝试分配的BindingContextNull,我怀疑在您的情况下确实如此,这仍将引发异常。
下面示例中的GridBindingContext设置为视图模型(objGrid.BindingContext = objMyView2)。
然后,我们为我们的命令参数创建一个新的绑定,其中Source指向我们的视图模型(Source = objGrid.BindingContext)。
如果您运行下面的演示,您将在Output窗口中看到来自视图模型的属性值的调试消息。
        MyView2 objMyView2 = new MyView2();
        objMyView2.SomeProperty1 = "value1";
        objMyView2.SomeProperty2 = "value2";

        objMyView2.LaunchLocationDetailsCommand_WithParameters = new Command<object>((o2)=>
        {
            LaunchingCommands.LaunchLocationDetailsCommand_WithParameters(o2);
        });

        Grid objGrid = new Grid();
        objGrid.BindingContext = objMyView2;
        objGrid.HeightRequest = 200; 
        objGrid.BackgroundColor = Color.Red;

        TapGestureRecognizer objTapGestureRecognizer = new TapGestureRecognizer();
        objTapGestureRecognizer.SetBinding(TapGestureRecognizer.CommandProperty, new Binding("LaunchLocationDetailsCommand_WithParameters"));

        Binding objBinding1 = new Binding()
        {
            Source = objGrid.BindingContext
        };
        objTapGestureRecognizer.SetBinding(TapGestureRecognizer.CommandParameterProperty, objBinding1);
        //
        objGrid.GestureRecognizers.Add(objTapGestureRecognizer);

支持的类别:

MyView2

public class MyView2
    : ViewModelBase
{
    public string SomeProperty1 { get; set; }
    public string SomeProperty2 { get; set; }

    public ICommand LaunchLocationDetailsCommand_WithParameters { get; set; }
}

启动命令

public static class LaunchingCommands
{
    public static void LaunchLocationDetailsCommand_WithParameters(object pobjObject)
    {
        System.Diagnostics.Debug.WriteLine("SomeProperty1 = " + (pobjObject as MyView2).SomeProperty1);
    }
}

ViewModelBase:-

public abstract class ViewModelBase
    : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void RaisePropertyChanged(string pstrPropertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(pstrPropertyName));
        }
    }

}

2
如果您使用 {Binding},但是里面没有放任何东西,那么它会绑定到绑定上下文并将其通过。因此,您需要将其绑定到页面的默认绑定上下文。
当您创建新绑定时,请设置数据源。
var binding = new Xamarin.Forms.Binding() { Source = this.BindingContext };

正如我在问题中提到的那样,你不能以我尝试的方式传递BindingContext。你建议怎么做? - tarrball

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接