簡體   English   中英

如何通過 xaml 屬性將值傳遞到自定義 ContentView 視圖模型

[英]How do I pass values through xaml properties into custom ContentView viewmodel

我正在嘗試通過我制作的自定義內容視圖上的屬性傳遞值。 我希望有一個父頁面能夠聲明自定義視圖的實例,並在需要時傳入一個 ID。 我希望自定義視圖接收到 ID,然后應該在視圖的視圖模型中設置屬性。 目前我的嘗試沒有成功,似乎視圖模型永遠不會更新它的 ID。 每次我運行它時,標簽中顯示的 ID 都是一個空的 guid。

帶有正確和不正確指南的標簽

我在項目中定義了以下四個類:

我創建主頁的實際應用程序: App

C# (App.xaml.cs)

using ExampleDataBinding.Views;
using Xamarin.Forms;

namespace ExampleDataBinding
{
    public partial class App : Application
    {

        public App()
        {
            InitializeComponent();

            MainPage = new TestMainPage();
        }

        protected override void OnStart()
        {
        }

        protected override void OnSleep()
        {
        }

        protected override void OnResume()
        {
        }
    }
}

我的應用程序中顯示的主頁: TestMainPage

XAML ( TestMainPage.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:views="clr-namespace:ExampleDataBinding.Views" 
             x:Class="ExampleDataBinding.Views.TestMainPage"
             x:DataType="views:TestMainPage">
    <ContentPage.Content>
        <StackLayout>
            <Label Text="{Binding MainPageID}" />
            <views:TestContentView ArbitraryGuid="{Binding MainPageID}"/>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

C# ( TestMainPage.xaml.cs )

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace ExampleDataBinding.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class TestMainPage : ContentPage
    {
        private Guid mainPageID = Guid.NewGuid();
        public Guid MainPageID
        {
            get => mainPageID;
            set => mainPageID = value;
        }

        public TestMainPage()
        {
            InitializeComponent();
            BindingContext = this;
        }

    }
}

主頁面試圖加載的視圖: TestContentView

XAML ( TestContentView.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" 
             xmlns:viewmodels="clr-namespace:ExampleDataBinding.ViewModels"
             x:Class="ExampleDataBinding.Views.TestContentView"
             x:DataType="viewmodels:TestContentViewModel">
    <ContentView.Content>
        <Label Text="{Binding Guid}" />
    </ContentView.Content>
</ContentView>

C# ( TestContentView.xaml.cs )

using ExampleDataBinding.ViewModels;
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace ExampleDataBinding.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class TestContentView : ContentView
    {
        public static readonly BindableProperty ArbitraryGuidProperty = BindableProperty.Create(nameof(ArbitraryGuid),
                                                                                                typeof(Guid?),
                                                                                                typeof(TestContentView),
                                                                                                null,
                                                                                                BindingMode.TwoWay,
                                                                                                propertyChanged: ArbitraryGuidPropertyChanged);

        private static void ArbitraryGuidPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var currentTestContentView = bindable as TestContentView;
            currentTestContentView.UpdateViewModelGuid();
        }

        private void UpdateViewModelGuid()
        {
            if(ArbitraryGuid.HasValue)
                viewModel.Guid = ArbitraryGuid.Value;
        }

        public Guid? ArbitraryGuid
        {
            get => (Guid?)GetValue(ArbitraryGuidProperty);
            set => SetValue(ArbitraryGuidProperty, value);
        }

        private TestContentViewModel viewModel;

        public TestContentView()
        {
            InitializeComponent();
            BindingContext = viewModel = new TestContentViewModel();
        }

    }
}

TestContentView的視圖模型: TestContentViewModel

C# ( TestContentViewModel.cs )

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace ExampleDataBinding.ViewModels
{
    public class TestContentViewModel : INotifyPropertyChanged
    {
        private Guid guid = Guid.Empty;
        public Guid Guid
        {
            get => guid;
            set => SetProperty(ref guid, value);
        }

        protected bool SetProperty<T>(ref T backingStore, T value,
                                        [CallerMemberName] string propertyName = "",
                                        Action onChanged = null)
        {
            if (EqualityComparer<T>.Default.Equals(backingStore, value))
                return false;

            backingStore = value;
            onChanged?.Invoke();
            OnPropertyChanged(propertyName);
            return true;
        }

        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            var changed = PropertyChanged;
            if (changed == null)
                return;

            changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }
}

我認為我應該能夠讓我的TestMainPage創建一個TestContentView並通過 Xaml 參數傳入任意值,但我對它的實際工作方式感到困惑。

我想保留TestContentView使用它自己的視圖模型,如果可能的話,它會從綁定或屬性值中填充。

我可能會在這里完全錯誤的方向,所以歡迎任何建議。 感謝您的任何指點!

TestMainPage 沒有設置 BindingContext。
所以{Binding MainPageID}沒有連接到任何東西。
在 TestMainPage.xaml.cs 中:

public TestMainPage()
{
    InitializeComponent();
    BindingContext = this;
}

或者,如果您將 ViewModel 添加到 TestMainPage,則將 MainPageID 移動到該 VM。 並將 BindingContext 設置為 VM。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM