c# - Xamarin.Forms 绑定(bind)不起作用

标签 c# xaml xamarin mvvm xamarin.forms

我尝试使用 XAML 将适用于 Windows10 的 UWP C# 应用重写为 Xamarin 应用。但是绑定(bind)(例如 ListView ItemSource=... 中的示例)对我不起作用,我不知道为什么。

Visual Studio tells me, Cannot Resolve Symbol Recording due to unknown Data Context.

这是我用于测试目的的 XAML (MainPage.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:local="clr-namespace:XamarinTest;assembly=XamarinTest"
             x:Class="XamarinTest.MainPage">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="100" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="100" />
        </Grid.ColumnDefinitions>
        <ListView x:Name="listView" IsVisible="false" ItemsSource="{Binding Recording}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <ViewCell.View>
                            <StackLayout Orientation="Horizontal">
                                <Image Source="Accept" WidthRequest="40" HeightRequest="40" />
                                <StackLayout Orientation="Vertical" HorizontalOptions="StartAndExpand">
                                    <Label Text="TEST" HorizontalOptions="FillAndExpand" />
                                    <Label Text="TEST" />
                                </StackLayout>
                            </StackLayout>
                        </ViewCell.View>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</ContentPage>

这是 C# (MainPage.xaml.cs):

namespace XamarinTest
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            this.InitializeComponent();
            this.AllTestViewModel = new RecordingViewModel();
            this.BindingContext = AllTestViewModel;                
        }
        public RecordingViewModel AllTestViewModel { get; set; }
    }
}

最后是 ViewModel(RecordingViewModel.cs):

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using XamarinTest.Model;

namespace XamarinTest.ViewModel
{
    public class RecordingViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<Recording> Recordings { get; } = new TrulyObservableCollection<Recording>();

        public RecordingViewModel()
        {
            Recordings.Add(new RecordingTest2()
            {
                TestName = "Test 1",
                TestNote = "Vytvoreni DB",
                TestTime = new TimeSpan(0, 0, 0)
            });
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    public sealed class TrulyObservableCollection<T> : ObservableCollection<T>
        where T : INotifyPropertyChanged
    {
        public TrulyObservableCollection()
        {
            CollectionChanged += FullObservableCollectionCollectionChanged;
        }

        public TrulyObservableCollection(IEnumerable<T> pItems) : this()
        {
            foreach (var item in pItems)
            {
                this.Add(item);
            }
        }

        private void FullObservableCollectionCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems != null)
            {
                foreach (Object item in e.NewItems)
                {
                    ((INotifyPropertyChanged)item).PropertyChanged += ItemPropertyChanged;
                }
            }
            if (e.OldItems != null)
            {
                foreach (Object item in e.OldItems)
                {
                    ((INotifyPropertyChanged)item).PropertyChanged -= ItemPropertyChanged;
                }
            }
        }

        private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            NotifyCollectionChangedEventArgs args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, sender, sender, IndexOf((T)sender));
            OnCollectionChanged(args);
        }
    }
}

一切(模型和 View 模型)都在 native UWP Windows 10 应用程序中运行。只有绑定(bind)和创建相同的 View 是 Xamarin 中的问题。有人可以帮忙绑定(bind)吗? 谢谢。

编辑

Recording.cs 在这里:

using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace XamarinTest.Model
{
    public abstract class Recording : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public string TestName { get; set; }
        private TimeSpan _testTime;
        private string _testNote;
        private string _actualIco = "Play";
        private bool _isActive = false;
        private bool _enabled = true;
        public double IcoOpacity { get; private set; } = 1.0;
        public string ActualIco
        {
            get => _actualIco;
            set
            {
                if (_actualIco == null) _actualIco = "Admin";
                _actualIco = value;
                NotifyPropertyChanged("ActualIco");
            }
        }
        public bool IsActive
        {
            get => _isActive;
            set
            {
                if (_isActive == value) return;
                _isActive = value;
                IcoOpacity = !value ? 1.0 : 0.3;
                NotifyPropertyChanged("IsActive");
                NotifyPropertyChanged("IcoOpacity");
            }
        }
        public bool Enabled
        {
            get => _enabled;
            set
            {
                if (_enabled == value) return;
                _enabled = value;
                NotifyPropertyChanged("Enabled");
            }
        }
        public string TestNote
        {
            get => _testNote;
            set
            {
                if (_testNote == value) return;
                _testNote = value;
                NotifyPropertyChanged("TestNote");
            }
        }
        public TimeSpan TestTime
        {
            get => _testTime;
            set
            {
                if (_testTime == value) return;
                _testTime = value;
                NotifyPropertyChanged("TestTime");
            }
        }

        protected Recording()
        {
            TestName = "Unkonwn";
            TestNote = "";
            _testTime = new TimeSpan(0, 0, 0);
        }

        protected Recording(string testName, string testNote, TimeSpan testTime)
        {
            TestName = testName;
            TestNote = testNote;
            _testTime = testTime;
        }
        public string OneLineSummary => $"{TestName}, finished: "
                                        + TestTime;

        private void NotifyPropertyChanged(string propertyName = "")
        {
            var handler = PropertyChanged;
            handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public abstract bool playTest();

    }
}

我尝试在 XAML 中添加 DataContext(postet in origin 问题),因为这样的智能:

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
xmlns:dvm="clr-namespace:XamarinTest.ViewModel"
xmlns:system="clr-namespace:System;assembly=System.Runtime"
d:DataContext="{system:Type dvm:RecordingViewModel}"

这是网格:

<Label Text="{Binding Recordings[0].TestName}" Grid.Row="0" Grid.Column="2" />

IntelliSence 正常,但文本不显示在应用程序中。

最佳答案

终于开始工作了!

XAML 应该类似于下面的代码。 重要的是 xmls:viewModel="..."<ContentPage.BindingContext>...</> .

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"                                                  
             xmlns:viewModel="clr-namespace:XamarinTest.ViewModel;assembly=XamarinTest"
             x:Class="XamarinTest.MainPage"         
             >
    <ContentPage.BindingContext>
        <viewModel:RecordingViewModel/>
    </ContentPage.BindingContext>
<ListView x:Name="listView" ItemsSource="{Binding Recordings}" Grid.Row="1" Grid.Column="1">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <ViewCell.View>
                            <StackLayout Orientation="Horizontal">
                                <Image Source="Accept" WidthRequest="40" HeightRequest="40" />
                                <StackLayout Orientation="Vertical" HorizontalOptions="StartAndExpand">
                                    <Label Text="{Binding TestName}" HorizontalOptions="FillAndExpand" />
                                    <Label Text="{Binding TestNote}" />
                                </StackLayout>
                            </StackLayout>
                        </ViewCell.View>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</ContentPage>

MainPage.xaml.cs 正常

namespace XamarinTest
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            this.InitializeComponent();
            this.AllTestViewModel = new RecordingViewModel();
            this.BindingContext = AllTestViewModel;                
        }
        public RecordingViewModel AllTestViewModel { get; set; }
    }
}

关于c# - Xamarin.Forms 绑定(bind)不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44297766/

相关文章:

c# - 在C#中使用OpenCV进行框架化

WPF 列表框数据绑定(bind)适用于设计器,但不适用于运行时

wpf - 在 WPF 中的单个 GeometryDrawing 中使用多个画笔

c# - 使用 xamarin (ios) 扫描本地网络中的设备

Android服务导致内存问题

c# - 优化代码,使其执行得更快

c# - 比较 2 个列表

C# MySQL 参数化更新不返回任何内容

c# - WPF 中的分辨率独立性如何工作?

ios - Visual Studio 2019中的问题:对iTunes Connect的请求限制已达到?(Xamarin Project)