在 C# 中添加到现有 TableView 的 Xamarin Forms EntryCell 无法在 CustomViewModel 中访问
Xamarin Forms EntryCell added to an existing TableView in c# cannot be accssed in CustomViewModel
我是 Xamarin Forms 的新手。我在 c# 中将 EntryCell 添加到 TableView 的现有 TableSection 中。我正在尝试访问 EntryCell 在 CustomViewModel 中输入的值,但我无法从我的 customviewmodel 访问它。
TabbedPage1
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:behaviors="clr-namespace:FamTreeApp.Behaviors" xmlns:local="clr-namespace:FamTreeApp.Views"
x:Class="FamTreeApp.Views.TabbedPage1">
<TabbedPage.Behaviors>
<behaviors:TabbedPageNavigationBehavior />
</TabbedPage.Behaviors>
<TabbedPage.Children>
<local:Tab1 Title ="Tab1" class="material-icons" Icon ="user.png" />
<local:Tab2 Title="Tab2" class="material-icons" Icon ="sharp_group_add_black_18.png" />
</TabbedPage.Children>
</TabbedPage>
Tab1.xaml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="FamTreeApp.Views.Tab1">
<TableView x:Name="SpouseTable" Intent="Form">
<TableRoot>
<TableSection x:Name="SpouseTS" Title="Parents">
<ViewCell>
<StackLayout x:Name="SpouseStack">
<Button Text="Submit" Clicked="OnSubmit"></Button>
</StackLayout>
</ViewCell>
</TableSection>
</TableRoot>
</TableView>
</ContentPage>
Tab1.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace FamTreeApp.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Tab1 : ContentPage
{
public Tab1()
{
InitializeComponent();
}
private void OnSubmit(object sender, EventArgs e)
{
EntryCell entInput = new EntryCell
{
Placeholder = "Name"
};
string txt = "{Binding Name}";
entInput.SetBinding(EntryCell.TextProperty, txt);
SpouseTS.Add(entInput);
}
}
}
Tab2.xaml
ontentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="FamTreeApp.Views.Tab2">
<ContentPage.Content>
<StackLayout>
<Label Text="Welcome to Xamarin.Forms!"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
Tab2.xaml.cs
public partial class Tab2 : ContentPage
{
public Tab2()
{
InitializeComponent();
}
}
ViewModelBase.cs
public class ViewModelBase : BindableBase, INavigationAware
{
private readonly INavigationService navigationService;
public ViewModelBase(INavigationService navigationService)
{
this.navigationService = navigationService;
}
private string title;
public string Title
{
get => this.title;
set => SetProperty(ref this.title, value);
}
public virtual void OnNavigatedFrom(INavigationParameters parameters) { }
public virtual void OnNavigatedTo(INavigationParameters parameters) { }
public virtual void OnNavigatingTo(INavigationParameters parameters) { }
}
TabbedPageNavigationBehavior
using Prism.Behaviors;
using Prism.Common;
using Prism.Navigation;
using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;
namespace FamTreeApp.Behaviors
{
public class TabbedPageNavigationBehavior : BehaviorBase<TabbedPage>
{
private Page CurrentPage;
protected override void OnAttachedTo(TabbedPage bindable)
{
bindable.CurrentPageChanged += this.OnCurrentPageChanged;
base.OnAttachedTo(bindable);
}
protected override void OnDetachingFrom(TabbedPage bindable)
{
bindable.CurrentPageChanged -= this.OnCurrentPageChanged;
base.OnDetachingFrom(bindable);
}
private void OnCurrentPageChanged(object sender, EventArgs e)
{
var newPage = this.AssociatedObject.CurrentPage;
if (this.CurrentPage != null)
{
var parameters = new NavigationParameters();
PageUtilities.OnNavigatedFrom(this.CurrentPage, parameters);
PageUtilities.OnNavigatedTo(newPage, parameters);
}
this.CurrentPage = newPage;
}
}
}
Tab1Model.cs
using Prism;
using Prism.Navigation;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Prism.Navigation.TabbedPages;
using FamTreeApp.Models;
using FamTreeApp.Views;
namespace FamTreeApp.ViewModels
{
public class Tab1Model : ViewModelBase
{
public Tab1Model(INavigationService navigationService)
: base(navigationService)
{
this.Title = nameof(Tab1);
}
public override void OnNavigatedFrom(INavigationParameters parameters)
{
base.OnNavigatedFrom(parameters);
**parameters.Add(nameof(this.Name), this.Name);**
}
}
}
Tab2Model.cs
using System;
using System.Collections.Generic;
using System.Text;
//using FamTreeApp.ViewModels.FamTreeApp.Views;
using Prism;
using Prism.Navigation;
//using FamTreeApp.ViewModels.FamTreeApp.Models;
namespace FamTreeApp.ViewModels
{
namespace FamTreeApp.ViewModels
{
public class Tab2Models : ViewModelBase
{
private string name;
public Tab2Models(INavigationService navigationService)
: base(navigationService)
{
//this.Title = nameof(Tab2);
}
public override void OnNavigatedFrom(INavigationParameters parameters)
{
base.OnNavigatedFrom(parameters);
}
}
}
}
App.xaml.cs
using Prism;
using Prism.Ioc;
using FamTreeApp.ViewModels;
using FamTreeApp.Views;
using Xamarin.Essentials.Interfaces;
using Xamarin.Essentials.Implementation;
using Xamarin.Forms;
using Prism.DryIoc;
using Prism.Navigation;
using Xamarin.Forms.Xaml;
namespace FamTreeApp
{
public partial class App : PrismApplication
{
public App() : this(null) { }
public App(IPlatformInitializer initializer) : base(initializer) { }
protected override async void OnInitialized()
{
InitializeComponent();
await this.NavigationService.NavigateAsync(nameof(TabbedPage1));
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<TabbedPage1>();
containerRegistry.RegisterForNavigation<Tab1, Tab1Model>();
containerRegistry.RegisterForNavigation<Tab2, Tab2Models>();
}
}
}
如何在其 ViewModel - Tab1Models 中访问 EntryCell(在单击提交按钮时创建)的值?在这里,我使用了 Prism,如何在有或没有 Prism 的情况下访问新创建的 EntryCell 及其自定义 ViewModel 的值?
首先,您没有正确使用SetBinding
private void OnSubmit(object sender, EventArgs e)
{
EntryCell entInput = new EntryCell
{
Placeholder = "Name"
};
// bind to a property "Name"
entInput.SetBinding(EntryCell.TextProperty, "Name");
SpouseTS.Add(entInput);
}
然后在您的 VM 中您需要 Name
属性
public class Tab1Model : ViewModelBase
{
public Tab1Model(INavigationService navigationService)
: base(navigationService)
{
this.Title = nameof(Tab1);
}
public string Name { get; set; }
public override void OnNavigatedFrom(INavigationParameters parameters)
{
base.OnNavigatedFrom(parameters);
parameters.Add(nameof(this.Name), this.Name);
}
}
请注意,我假设您的 BindingContext
设置正确或 Prism 正在为您完成 - 我不熟悉 Prism 如何处理
我是 Xamarin Forms 的新手。我在 c# 中将 EntryCell 添加到 TableView 的现有 TableSection 中。我正在尝试访问 EntryCell 在 CustomViewModel 中输入的值,但我无法从我的 customviewmodel 访问它。
TabbedPage1
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:behaviors="clr-namespace:FamTreeApp.Behaviors" xmlns:local="clr-namespace:FamTreeApp.Views"
x:Class="FamTreeApp.Views.TabbedPage1">
<TabbedPage.Behaviors>
<behaviors:TabbedPageNavigationBehavior />
</TabbedPage.Behaviors>
<TabbedPage.Children>
<local:Tab1 Title ="Tab1" class="material-icons" Icon ="user.png" />
<local:Tab2 Title="Tab2" class="material-icons" Icon ="sharp_group_add_black_18.png" />
</TabbedPage.Children>
</TabbedPage>
Tab1.xaml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="FamTreeApp.Views.Tab1">
<TableView x:Name="SpouseTable" Intent="Form">
<TableRoot>
<TableSection x:Name="SpouseTS" Title="Parents">
<ViewCell>
<StackLayout x:Name="SpouseStack">
<Button Text="Submit" Clicked="OnSubmit"></Button>
</StackLayout>
</ViewCell>
</TableSection>
</TableRoot>
</TableView>
</ContentPage>
Tab1.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace FamTreeApp.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Tab1 : ContentPage
{
public Tab1()
{
InitializeComponent();
}
private void OnSubmit(object sender, EventArgs e)
{
EntryCell entInput = new EntryCell
{
Placeholder = "Name"
};
string txt = "{Binding Name}";
entInput.SetBinding(EntryCell.TextProperty, txt);
SpouseTS.Add(entInput);
}
}
}
Tab2.xaml
ontentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="FamTreeApp.Views.Tab2">
<ContentPage.Content>
<StackLayout>
<Label Text="Welcome to Xamarin.Forms!"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
Tab2.xaml.cs
public partial class Tab2 : ContentPage
{
public Tab2()
{
InitializeComponent();
}
}
ViewModelBase.cs
public class ViewModelBase : BindableBase, INavigationAware
{
private readonly INavigationService navigationService;
public ViewModelBase(INavigationService navigationService)
{
this.navigationService = navigationService;
}
private string title;
public string Title
{
get => this.title;
set => SetProperty(ref this.title, value);
}
public virtual void OnNavigatedFrom(INavigationParameters parameters) { }
public virtual void OnNavigatedTo(INavigationParameters parameters) { }
public virtual void OnNavigatingTo(INavigationParameters parameters) { }
}
TabbedPageNavigationBehavior
using Prism.Behaviors;
using Prism.Common;
using Prism.Navigation;
using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;
namespace FamTreeApp.Behaviors
{
public class TabbedPageNavigationBehavior : BehaviorBase<TabbedPage>
{
private Page CurrentPage;
protected override void OnAttachedTo(TabbedPage bindable)
{
bindable.CurrentPageChanged += this.OnCurrentPageChanged;
base.OnAttachedTo(bindable);
}
protected override void OnDetachingFrom(TabbedPage bindable)
{
bindable.CurrentPageChanged -= this.OnCurrentPageChanged;
base.OnDetachingFrom(bindable);
}
private void OnCurrentPageChanged(object sender, EventArgs e)
{
var newPage = this.AssociatedObject.CurrentPage;
if (this.CurrentPage != null)
{
var parameters = new NavigationParameters();
PageUtilities.OnNavigatedFrom(this.CurrentPage, parameters);
PageUtilities.OnNavigatedTo(newPage, parameters);
}
this.CurrentPage = newPage;
}
}
}
Tab1Model.cs
using Prism;
using Prism.Navigation;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Prism.Navigation.TabbedPages;
using FamTreeApp.Models;
using FamTreeApp.Views;
namespace FamTreeApp.ViewModels
{
public class Tab1Model : ViewModelBase
{
public Tab1Model(INavigationService navigationService)
: base(navigationService)
{
this.Title = nameof(Tab1);
}
public override void OnNavigatedFrom(INavigationParameters parameters)
{
base.OnNavigatedFrom(parameters);
**parameters.Add(nameof(this.Name), this.Name);**
}
}
}
Tab2Model.cs
using System;
using System.Collections.Generic;
using System.Text;
//using FamTreeApp.ViewModels.FamTreeApp.Views;
using Prism;
using Prism.Navigation;
//using FamTreeApp.ViewModels.FamTreeApp.Models;
namespace FamTreeApp.ViewModels
{
namespace FamTreeApp.ViewModels
{
public class Tab2Models : ViewModelBase
{
private string name;
public Tab2Models(INavigationService navigationService)
: base(navigationService)
{
//this.Title = nameof(Tab2);
}
public override void OnNavigatedFrom(INavigationParameters parameters)
{
base.OnNavigatedFrom(parameters);
}
}
}
}
App.xaml.cs
using Prism;
using Prism.Ioc;
using FamTreeApp.ViewModels;
using FamTreeApp.Views;
using Xamarin.Essentials.Interfaces;
using Xamarin.Essentials.Implementation;
using Xamarin.Forms;
using Prism.DryIoc;
using Prism.Navigation;
using Xamarin.Forms.Xaml;
namespace FamTreeApp
{
public partial class App : PrismApplication
{
public App() : this(null) { }
public App(IPlatformInitializer initializer) : base(initializer) { }
protected override async void OnInitialized()
{
InitializeComponent();
await this.NavigationService.NavigateAsync(nameof(TabbedPage1));
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<TabbedPage1>();
containerRegistry.RegisterForNavigation<Tab1, Tab1Model>();
containerRegistry.RegisterForNavigation<Tab2, Tab2Models>();
}
}
}
如何在其 ViewModel - Tab1Models 中访问 EntryCell(在单击提交按钮时创建)的值?在这里,我使用了 Prism,如何在有或没有 Prism 的情况下访问新创建的 EntryCell 及其自定义 ViewModel 的值?
首先,您没有正确使用SetBinding
private void OnSubmit(object sender, EventArgs e)
{
EntryCell entInput = new EntryCell
{
Placeholder = "Name"
};
// bind to a property "Name"
entInput.SetBinding(EntryCell.TextProperty, "Name");
SpouseTS.Add(entInput);
}
然后在您的 VM 中您需要 Name
属性
public class Tab1Model : ViewModelBase
{
public Tab1Model(INavigationService navigationService)
: base(navigationService)
{
this.Title = nameof(Tab1);
}
public string Name { get; set; }
public override void OnNavigatedFrom(INavigationParameters parameters)
{
base.OnNavigatedFrom(parameters);
parameters.Add(nameof(this.Name), this.Name);
}
}
请注意,我假设您的 BindingContext
设置正确或 Prism 正在为您完成 - 我不熟悉 Prism 如何处理