代码之家  ›  专栏  ›  技术社区  ›  John Livermore

Xamarin窗体自定义控件数据绑定问题

  •  0
  • John Livermore  · 技术社区  · 7 年前

    我有一个简单的自定义控件,它无法使公开的可绑定命令属性正常工作。

    设置如下:mainpage.xaml hosts customcontrol.xaml( 下方米色区域 )CustomControl包含一个标签和一个按钮。主页包含自定义控件、条目、标签和按钮。所有控件都绑定到MainPageViewModel中的CustomControlText属性。因此,当该属性更改时,所有控件都应更新。

    它主要起作用…

    看看下面的演示视频。我单击主页上的按钮,所有控件都会更新,包括自定义控件。当我更改输入值时,所有字段都会更新。但是,单击“从CustomControl递增”不起任何作用。它应该调用MainViewModel中的SubmitCommand2。

    enter image description here

    我的所有代码都在下面(简单文件/新项目示例)。如何更改此代码,以便单击“increment from customcontrol”最终调用mainpageviewmodel中的submitcommand2命令?

    主页.xaml

    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:local="clr-namespace:App7"
                 x:Class="App7.MainPage">
    
        <StackLayout>
            <BoxView HeightRequest="100" />
    
            <local:CustomControl 
                Margin="50"
                WidthRequest="300"
                TextData="{Binding CustomControlText}" 
                Command="{Binding SubmitCommand2}"
            />
    
            <Entry Text="{Binding CustomControlText}" />
    
            <Label Text="{Binding CustomControlText}" />
    
            <Button Text="Increment from Main Page" Command="{Binding SubmitCommand}" />
    
        </StackLayout>
    
    </ContentPage>
    

    主页.xaml.cs

    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }
    }
    

    主页Model.cs

    public class MainPageModel : FreshBasePageModel
    {
        public MainPageModel() { }
    
        public string CustomControlText { get; set; }
    
        private int _index = 0;
    
        public Command SubmitCommand
        {
            get
            {
                return new Command(() =>
                {
                    _index++;
                    CustomControlText = $"Hello World {_index}";
                });
            }
        }
    
        public Command SubmitCommand2
        {
            get
            {
                return new Command(() =>
                {
                    _index++;
                    _index++;
                    CustomControlText = $"Hello World {_index}";
                });
            }
        }
    
        public override void Init(object initData)
        {
            CustomControlText = "Hello World";
    
            base.Init(initData);
        }
    }
    

    自定义控件.xaml

    <ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="App7.CustomControl"
                 BackgroundColor="Beige"
                 x:Name="this">
        <ContentView.Content>
            <StackLayout>
                <Entry x:Name="entryControl"
                    Placeholder="Enter Text"
                    Text="{Binding Source={x:Reference this}, Path=TextData}"
                />
                <Button Text="Increment From CustomControl"
                    Command="{Binding Source={x:Reference this}, Path=Command}"
                />
            </StackLayout>
        </ContentView.Content>
    </ContentView>
    

    自定义控件.xaml.cs

    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class CustomControl : ContentView
    {
        public CustomControl()
        {
            TextData = "";
    
            InitializeComponent();
        }
    
        public static readonly BindableProperty TextDataProperty = BindableProperty.Create(
                                                   propertyName: "TextData",
                                                   returnType: typeof(string),
                                                   declaringType: typeof(CustomControl),
                                                   defaultBindingMode: BindingMode.TwoWay,
                                                   defaultValue: "");
    
        public string TextData
        {
            get { return base.GetValue(TextDataProperty).ToString(); }
            set { base.SetValue(TextDataProperty, value); }
        }
    
        public static readonly BindableProperty CommandProperty = BindableProperty.Create(
                                                   propertyName: "Command",
                                                   returnType: typeof(Command),
                                                   declaringType: typeof(CustomControl),
                                                   defaultBindingMode: BindingMode.OneWay);
    
        public Command Command { get; set; }
    }
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   foxanna    7 年前

    这个 Command 的属性 CustomControl 也应该用 base.GetValue 和 base.SetValue ,与 TextData 是。

    public partial class CustomControl : ContentView
    {
        ...
    
        public static readonly BindableProperty CommandProperty =   
            BindableProperty.Create(
                propertyName: nameof(Command),
                returnType: typeof(ICommand),
                declaringType: typeof(CustomControl),
                defaultBindingMode: BindingMode.OneWay,
                defaultValue: default(ICommand));
    
        public ICommand Command 
        {
            get => (ICommand) GetValue(CommandProperty);
            set => SetValue(CommandProperty, value);
        }
    }
    
    推荐文章