2017-01-19 37 views
2

前几天我开始学习XAML,并且在解决这个问题时遇到了麻烦。Xamarin - 用户控件内部对象的属性绑定命令

在Xamarin Forms中,我想创建一个用户控件,它将包含一个标签和一个按钮,并且能够从使用我的用户控件的另一页面将命令绑定到XAML中的usercontrol。

我目前得到的异常:

Xamarin.Forms.Xaml.XamlParseException:“职位8:24。无法指定属性“Test1”:属性不存在,或者不可分配,或者值与属性之间的配型不匹配'

这是一个虚拟版本,我目前正在努力工作。用我的自定义控件XAML

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      xmlns:local="clr-namespace:App3" 
      xmlns:controls="clr-namespace:App3.Controls" 
      x:Class="App3.MainPage"> 

    <controls:Control1 Test1="{Binding Test2}" /> 
</ContentPage> 

我的自定义控制代码隐藏

using System.Windows.Input; 
using Xamarin.Forms; 

namespace App3.Controls 
{ 
    public partial class Control1 : ContentView 
    { 

     private static readonly BindableProperty controlProperty = BindableProperty.Create("Test1", typeof(ICommand), typeof(Control1), null); 

     public Control1() 
     { 
      InitializeComponent(); 
     } 

     public ICommand Test1 
     { 
      get 
      { 
       return (ICommand)GetValue(controlProperty); 
      } 
      set 
      { 
       SetValue(controlProperty, value); 
      } 
     } 

    } 
} 
使用自定义控制页面的

视图模型

我的自定义控制XAML

<?xml version="1.0" encoding="UTF-8"?> 
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="App3.Controls.Control1"> 
    <StackLayout> 
     <Button Command="{Binding Test1}" Text="Test"/> 
    </StackLayout> 
</ContentView> 

控制

using System.ComponentModel; 
using System.Runtime.CompilerServices; 
using System.Windows.Input; 
using Xamarin.Forms; 

namespace App3 
{ 
    public class MainPageViewModel : INotifyPropertyChanged 
    { 
     public MainPageViewModel() 
     { 
      this.Test2 = new Command(test); 
     } 

     public void test() 
     { 
      Application.Current.MainPage.DisplayAlert("it works", "it works", "it works"); 
     } 

     public ICommand Test2 
     { 
      get; set; 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
     protected void OnPropertyChanged([CallerMemberName] string propertyName = null) 
     { 
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

回答

12

有一些命名约定,如果你希望你的BindableProperty检测可循的,可绑定,在XAML:

当用户通过属性的名称创建标识符字段名该字段为您注册它,加上后缀Property。该字段是依赖项属性的标识符,稍后将用作SetValue和GetValue调用的输入,您可以在包装中进行SetValue和GetValue调用,也可以通过任何其他代码访问属性(通过您自己的代码),通过任何外部代码访问您允许,通过属性系统,也可能通过XAML处理器。

定义DependencyProperty标识符作为所有者类型公共静态只读字段。

(这是DependencyProperty的文档,但是它适用于BindableProperties相当不错在这种情况下,见https://msdn.microsoft.com/en-us/library/ms753358(v=vs.110).aspx

您可以通过替换

private static readonly BindableProperty controlProperty = BindableProperty.Create("Test1", typeof(ICommand), typeof(Control1), null); 

public ICommand Test1 
{ 
    get { return (ICommand)GetValue(controlProperty); } 
    set { SetValue(controlProperty, value); } 
} 

通过

解决您的代码
public static readonly BindableProperty Test1Property = BindableProperty.Create("Test1", typeof(ICommand), typeof(Control1), null); 


public ICommand Test1 
{ 
    get { return (ICommand)GetValue(Test1Property); } 
    set { SetValue(Test1Property, value); } 
} 

这应该防止属性检测问题。

让你充满东西的工作,按钮命令结合应该有它的源设置为控制本身,你应该设置你的MainPageViewModelBindingContextMainPage

0

非常感谢你们两位,我已经和Krzysztof脱线了,在所有这些变化之后,还有一件事是让它工作。

现在,当您单击自定义控件中的按钮(Control1)绑定的命令将不会被调用时,绑定中保存的命令为空,但即使您通知视图以从bindablecontext获取新命令,也不会起作用,因为它不会找到适当的属性,因为我们没有指定bindablecontext,因此框架将在其他位置(在父对象中)搜索我们的属性。不要尝试将自定义控件的bindablecontext设置为此,它将制动绑定到此控件的能力(您将无法正确绑定到这些依赖项属性)。

在这种情况下解决它的最简单方法是在xaml中设置适当的绑定源。 设置您的内容视图的名称,并在绑定所有绑定时指定绑定源(这里只有一个)。

<?xml version="1.0" encoding="UTF-8"?> 
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
x:Class="App3.Controls.Control1" 
x:Name="MySpecifiedName"> 
    <StackLayout> 
     <Button Command="{Binding Test1, Source={x:Reference MySpecifiedName}}" Text="Test"/> 
    </StackLayout> 
</ContentView> 

我已经挖如何解决它的话,我写这里保存其面临的这些问题,其它的时间浪费了开发商几个小时。

相关问题