Krz*_*ona 5 c# xaml xamarin xamarin.forms
我几天前就开始学习XAML了,我遇到了解决这个问题的麻烦.
在Xamarin Forms中,我想创建一个用户控件,它将包含一个标签和一个按钮,并能够将命令绑定到XAML中的usercontrol来自另一个使用我的用户控件的页面.
我目前正在例外:
Xamarin.Forms.Xaml.XamlParseException:'位置8:24.无法分配属性"Test1":属性不存在,或者不可分配,或者值和属性之间的类型不匹配'
这是我目前正在努力工作的一个愚蠢的版本.
我的自定义控件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>
Run Code Online (Sandbox Code Playgroud)
使用我的自定义控件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>
Run Code Online (Sandbox Code Playgroud)
我的自定义控件代码隐藏
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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用自定义控件查看页面模型
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));
}
}
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*oix 15
如果您希望从Xaml检测到可绑定的BindableProperty,则需要遵循一些命名约定:
创建标识符字段时,请在注册时按属性名称命名此字段,再加上后缀属性.此字段是依赖项属性的标识符,稍后将用作您将在包装器中进行的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); }
}
Run Code Online (Sandbox Code Playgroud)
通过
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); }
}
Run Code Online (Sandbox Code Playgroud)
这应该可以防止属性检测问题.
让你充满东西的工作,按钮命令结合应该有它的源设置为控制本身,你应该设置你MainPageViewModel的BindingContext了MainPage.
非常感谢你们两位,我已经与 Krzysztof 进行了离线交谈,在所有这些更改之后,还剩下一件事可以使其正常工作。
现在,当您单击自定义控件(Control1)中的按钮时,绑定命令将不会被调用,绑定中保存的命令为空,但是即使您通知视图从 bindablecontext 获取新命令它也不会工作,因为它找不到正确的属性,因为我们没有指定 bindablecontext 所以框架将在其他地方(在父对象中)搜索我们的属性。不要尝试将自定义控件的 bindablecontext 设置为 this,它会阻止绑定到此控件的能力(您将无法正确绑定到那些依赖属性)。
在这种情况下,解决它的最简单方法是在 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>
Run Code Online (Sandbox Code Playgroud)
我已经浪费了几个小时来研究如何修复它,所以我写在这里是为了节省其他面临这些问题的开发人员的时间。
| 归档时间: |
|
| 查看次数: |
5025 次 |
| 最近记录: |