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

我尝试使用XAML将Windows10的UWP C#应用程序重写为Xamarin应用程序.但是绑定(例如,在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);
        }
    }
}

一切(模型和视图模型)都在本机UWP Windows 10应用程序中运行.在Xamarin中,只有绑定和创建相同的视图才是问题.有人可以帮忙装订吗?
谢谢.

编辑

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(起源中的问题),因为这样的才智:

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项目中以* CS.cs结尾的文件的用途是什么?


下一篇:CodeGo.net> MVVM-单击按钮在哪里调用功能?