【问题标题】:Xamarin.Forms Binding whole view inside a gridXamarin.Forms 在网格内绑定整个视图
【发布时间】:2022-01-17 16:28:57
【问题描述】:

我目前正在 Xamarin.Forms XAML 中训练一些绑定和 MVVM。 我有一个带有网格的视图,我想将整个视图作为一个孩子绑定到它。

此外,我正在使用 ZXing.Net.Mobile.Forms 和他们想要显示的视图。

以编程方式没有问题 grid.Children.Add(MyView);

但是如何使用 XAML 中的绑定实现相同的结果?


提前致谢!

视图应绑定到的我的 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"
             x:Class="ZxingNetMobileTemplate.ScannerView">
    <Grid BindingContext="{Binding .}" x:Name="test">
        
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="*" ></RowDefinition>
        </Grid.RowDefinitions>
        
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        
        <StackLayout Orientation="Horizontal">
            <Image Source="{Binding ImgSource}" HeightRequest="30" WidthRequest="30" HorizontalOptions="End" VerticalOptions="Start">
                <Image.GestureRecognizers>
                    <TapGestureRecognizer Tapped="OnTorchTapped"></TapGestureRecognizer>
                </Image.GestureRecognizers>
            </Image>
        </StackLayout>         
    </Grid>       
</ContentPage>

我的 Xaml.cs 和视图模型:

 public partial class ScannerView : ContentPage
    {
        public CameraViewModel CameraViewModel { get; private set; }

        public ScannerView(IEnumerable<BarcodeFormat> formats = null)
        {
            InitializeComponent();
            BindingContext = CameraViewModel is null ? CameraViewModel = new CameraViewModel(formats) : CameraViewModel;
        }

        protected override void OnAppearing()
        {
            base.OnAppearing();
            CameraViewModel.ScanAsync();
            //test.Children.Add(CameraViewModel.Scanner);
            //test.Children.Add(CameraViewModel.Overlay);
            SubscribeScanResult();
            CameraViewModel.Scanner.IsAnalyzing = true;
            CameraViewModel.Scanner.IsScanning = true;
        } 
}
... 

最后但并非最不重要的是我的视图模型,其中属性“扫描仪”和“覆盖”应绑定到 xaml

  public class CameraViewModel
    {
        public ZXingScannerView Scanner { get; private set; }
        public ZXingDefaultOverlay Overlay { get; private set; }
        public IEnumerable<BarcodeFormat> CustomFormats { get; private set; }
        public string ImgSource => Device.RuntimePlatform == Device.Android ? "thunder.png" : "Images/thunder.png";

        public CameraViewModel(IEnumerable<BarcodeFormat> formats)
        {
            CustomFormats = formats;
        }
...
}

【问题讨论】:

  • 需要更多信息。你有带 Grid 的 customView 你想在哪里绑定另一个视图(我假设一些 zxing 视图)?
  • 是的,我有正常的 XAML 文件,包括它的 .cs。我的 Zxing 东西在 Viewmodel CameraViewModel 中。在 ViewModel 绑定到的 xaml 中定义了一个网格。
  • 我会简单地添加更多代码
  • @puko 我添加了代码
  • 那么为什么在后面的代码中设置 CameraViewModel 时要使用绑定?对我来说使用绑定没有意义,只需通过 x:Name 访问网格并添加视图。

标签: c# .net xaml xamarin.forms data-binding


【解决方案1】:

像这样自定义“网格”

XAML

<ContentView
  ....>
  <ContentView.Content>
     <Grid x:Name="Grid">
         .... here is your default content
     </Grid>
   </ContentView.Content>
</ContentView>

.cs

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class View1 : ContentView
{
      public static readonly BindableProperty CustomViewProperty = BindableProperty.Create(nameof(CustomView), typeof(View), typeof(View1), null, propertyChanged: OnCustomViewChanged);
    
      public View1()
      {
         InitializeComponent();
      }
    
      public View CustomView
      {
          get { return (View)GetValue(CustomViewProperty); }
          set { SetValue(CustomViewProperty, value); }
      }
    
      static void OnCustomViewChanged(BindableObject bindable, object oldValue, object newValue)
      {
          //x:name Grid xaml
          //not sure if you want to clear grid before add new control
          //((View1)bindable).Grid.Children.Clear();
    
          ((View1)bindable).Grid.Children.Add((View)newValue);
      }
}

然后在您的 Xaml 而不是 Grid 中使用 View1(在我的情况下,请选择一些更好的名称 :))。

//not sure if you want to bind Scanner property
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ZxingNetMobileTemplate.ScannerView">
    <View1 CustomView="{Binding Scanner}">   
</ContentPage>

注意:拥有包含视图的 ViewModel 不是一个好习惯。想象一下,你想在不同的应用程序中使用这个 ViewModel,比如说 WPF。你不能,因为对 Zxing 有依赖。

【讨论】:

  • 嘿,你的代码对我来说不是 1:1 工作的,因为从 ContentView 派生的 View1 在事件处理中不包含 InitializeComponent() 方法也不包含 .Grid 我现在直接从 Grid 派生它并在那里添加它的孩子
  • View1 包含 InitalizeComponent 和 Grid(它是 Xaml 中 Grid 的名称)。我不想从 Grid 派生。我想隐藏 Children 财产。现在,当您从 Grid 派生时,Children 属性将被公开
  • 昨天给你发了一条消息到聊天室
猜你喜欢
  • 2016-03-15
  • 1970-01-01
  • 1970-01-01
  • 2015-12-12
  • 2016-03-31
  • 2020-09-28
  • 2014-08-17
  • 1970-01-01
  • 2015-12-22
相关资源
最近更新 更多