【问题标题】:Xamarin.Forms Prism App.xaml can be binded to a ViewModel?Xamarin.Forms Prism App.xaml 可以绑定到 ViewModel 吗?
【发布时间】:2019-05-28 15:01:37
【问题描述】:

我正在使用 Prism 构建一个 Xamarin.Forms 应用程序,它显示连接了哪些蓝牙设备。

在这个应用程序中,我需要在所有页面中显示设备连接状态的页脚。 为此,我创建了一个名为 Pen 的静态类,其属性 IsConnectedBleService 更新。

我还需要页脚中的按钮,当Pen 断开连接并且按下它时,我可以调用BleService 的 Connect 方法。

对于页脚,我在App.xaml 中创建了一个ControlTemplate,其中包含一个按钮。

现在,我正在使用 Prism,但我不知道如何将按钮绑定到 ViewModel(App.xaml 没有 ViewModel)以调用 BleService 的连接命令。

【问题讨论】:

    标签: xamarin xamarin.forms prism


    【解决方案1】:

    App.xamlApp.aml.cs 文件包含配置 Prism 应用程序并在启动时导航到根页面所需的逻辑。

    From the documentation

    所以你不能为此创建一个 ViewModel,因为它不是一个 View,这会破坏 MVVM 模式。 Prism 是一个 MVVM 框架,它通过导航服务加载视图(及其视图模型)来工作。因此,这种“全局”视图的方法不适用于绑定。

    创建control template 也不能解决这个问题,它只是允许您在app.xaml 中定义一个可重复使用的模板。

    我的建议是:

    1. 将此页脚添加到所有视图中,这有点开销。

    1. 在 BleService 更改时显示一个弹出窗口,而不是显示页脚视图。

    另一种选择是创建一些自定义渲染。您可以在 iOS 上添加 View to the RootViewController 本地执行此操作。对于其他平台,我不太确定,因此您可以通过一些自定义渲染器路径尝试使用页脚来获取它,但我认为这不值得头疼。

    同样不是理想的解决方案,但一些平台可以很好地控制这一点,所以我可以看到为什么 Xamarin.Forms 没有这个,内置的。

    【讨论】:

    • 非常感谢。我选择第一个解决方案。我不能再浪费时间了。
    • 如何使用 isVisible 创建一个局部视图,并在您想要显示它时在其他页面中将其作为 true 传递。容易得多。
    【解决方案2】:

    我找到了解决方案,但我想知道您的想法。

    在 App.Xaml 中,在控件模板中,我已经绑定了连接按钮的命令,如下所示:

    <buttons:SfButton Grid.Column="0" Grid.Row="2"
        Command="{TemplateBinding Parent.BindingContext.ConnectCommand}"
        IsVisible="{Binding IsNotConnected, Source={x:Static local:Pen.Current}}"/>
    

    然后我修改了 ViewModelBase 类,所以任何新的 View 都会继承蓝牙服务和命令执行的链接:

    public class ViewModelBase : BindableBase, INavigationAware, IDestructible
    {
        protected INavigationService NavigationService { get; private set; }
        protected IBLEService BLEService { get; private set; }
    
        private string _title;
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
    }
    
    public ViewModelBase(INavigationService nS,IBLEService bS)
    {
        NavigationService = nS;
        BLEService = bS;
    }
    
    public virtual void Destroy()
    {
    }
    
    private DelegateCommand connectCommand;
    public DelegateCommand ConnectCommand => connectCommand ?? 
        (connectCommand = new DelegateCommand(ExecuteConnectCommand));
    
    async void ExecuteConnectCommand()
    {
        await BLEService.Connect();
    }
    

    你怎么看? 非常感谢,祝您有美好的一天, 安德烈亚

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      • 2020-09-24
      • 2021-12-10
      • 1970-01-01
      • 2017-10-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多