【问题标题】:Binding property not found / some data displayed some not未找到绑定属性/某些数据未显示
【发布时间】:2021-01-23 23:03:45
【问题描述】:

我在显示数据时遇到问题,我可以在 List 属性中看到我的数据 FieldValue 和 FieldDescriptor 但是我仍然在输出中看到:

绑定:在“ViewModel.ResultPageViewModel”上找不到“Results”属性,目标属性:“Xamarin.Forms.ListView.ItemsSource”

我在水平列表视图中看不到任何数据FieldVisualData,即使我可以在视图模型中看到它们添加到细节并且也找不到命令。

绑定:在“Model.DocumentData”上找不到“EditTextCommand”属性,目标属性:“Xamarin.Forms.TapGestureRecognizer.Command”

也许你看到了我遗漏的东西?

 <StackLayout Spacing="0">
                <!--Pictures-->
        <StackLayout VerticalOptions="Start" Spacing="0" >  
               <controls:HorizontalScrollList VerticalOptions="Start" HeightRequest="300" x:Name="carouselView"  ItemsSource="{Binding Results, Mode=TwoWay}">
                    <controls:HorizontalScrollList.ItemTemplate>
                        <DataTemplate>
                            <Image Source="{Binding Results.FieldVisualData}" 
                                    Margin="5">
                                <!--<Image.GestureRecognizers>
                                    <TapGestureRecognizer
                                        Command="{Binding HandlePreviewTapped, Source={x:Reference vm}}"
                                        CommandParameter="{Binding}"/>
                                </Image.GestureRecognizers>-->
                            </Image>
                        </DataTemplate>
                    </controls:HorizontalScrollList.ItemTemplate>
                </controls:HorizontalScrollList>                          
        </StackLayout>
            
        <StackLayout  VerticalOptions="Start" BackgroundColor="{DynamicResource SeparatorLineColor}" Spacing="10">
              <!--DocumentData-->
             <Label Grid.Row="0" HorizontalOptions="CenterAndExpand" Text="Občanský průkaz" VerticalOptions="End" ></Label>
            <StackLayout BackgroundColor="{DynamicResource PageBackgroundColor}"  VerticalOptions="FillAndExpand">
                <ListView x:Name="list" BackgroundColor="{DynamicResource PageBackgroundColor}"
                    HasUnevenRows="True"
                    HorizontalOptions="CenterAndExpand"
                    VerticalOptions="CenterAndExpand"
                    VerticalScrollBarVisibility="Never"
                    CachingStrategy="RecycleElement"
                   ItemsSource="{Binding Results, Mode=TwoWay}"
                    SeparatorVisibility="Default"
                    SelectionMode="None">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                        <ViewCell>
                                <Grid  BackgroundColor="{DynamicResource PageBackgroundColor}" Padding="10" >
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="*"/>
                                        <ColumnDefinition Width="15*"/>
                                         <ColumnDefinition Width="*"/>
                                        <ColumnDefinition Width="12*"/>
                                        <ColumnDefinition Width="*"/>
                                    </Grid.ColumnDefinitions>
                                   <Label Grid.Column="1" Padding="0" Text ="{Binding FieldDescriptor}" Style="{StaticResource SubLabelBlackStyle}" HorizontalOptions="Start" BackgroundColor="{DynamicResource PageBackgroundColor}" HorizontalTextAlignment="Start"/>
                                   <Label Grid.Column="3" Padding="0" Text="{Binding FieldValue}" FontSize="Small" TextColor="#6781a3"  BackgroundColor="{DynamicResource PageBackgroundColor}" HorizontalOptions="Start" HorizontalTextAlignment="Start">
                                       <Label.GestureRecognizers>
                                           <TapGestureRecognizer Command="{Binding EditTextCommand}"  CommandParameter="{Binding FieldValue}" />
                                       </Label.GestureRecognizers>
                                   </Label>
                              </Grid>
                        </ViewCell>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </StackLayout>
        </StackLayout>    
</StackLayout>
public partial class ResultPage : ContentPage
{
    public ResultPage(IEnumerable<DocumentData> data)
    {
      InitializeComponent();
      BindingContext = new ResultPageViewModel(data);

       //carouselView.ItemsSource = data;
       // list.ItemsSource = data;
     
    }
}

public class ResultPageViewModel : BaseViewModel
{
    public ObservableCollection<DocumentData> Results { get; } = new ObservableCollection<DocumentData>();
    public ICommand EditTextCommand { get; }
    object param = "";
    public ResultPageViewModel(IEnumerable<DocumentData> data)
    {
        EditTextCommand = new Command(async () => await EditTextAsync(param));
        Load(data);
    }

    public void Load(IEnumerable<DocumentData> data)
    {
        foreach (var result in data)
        {
            var detail = new DocumentData()
            {
                FieldVisualData = result.FieldVisualData,
                FieldDescriptor = result.FieldDescriptor,
                FieldValue = result.FieldValue,
            };
            Results.Add(detail);
          
        }
    }

    public async Task EditTextAsync(object param)
    {
        PromptResult pResult = await UserDialogs.Instance.PromptAsync(new PromptConfig
        {
            InputType = InputType.Password,
            Text = param.ToString(),
            Title = Resources.AppResources.Password_lbl,
        });
    }
}

public static readonly BindableProperty ItemTemplateProperty = BindableProperty.Create( "项目模板", 类型(数据模板), typeof(Horizo​​ntalScrollList), 空值, propertyChanged: (bindable, value, newValue) => ((Horizo​​ntalScrollList)bindable).Populate());

    public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create(
        "ItemsSource",
        typeof(IEnumerable),
        typeof(HorizontalScrollList),
        null,
        BindingMode.OneWay,
        propertyChanged: (bindable, value, newValue) =>
        {
            var obs = value as INotifyCollectionChanged;
            var self = (HorizontalScrollList)bindable;
            if (obs != null)
                obs.CollectionChanged -= self.HandleItemChanged;

            self.Populate();

            obs = newValue as INotifyCollectionChanged;
            if (obs != null)
                obs.CollectionChanged += self.HandleItemChanged;
        });

    public IEnumerable ItemsSource
    {
        get => (IEnumerable)this.GetValue(ItemsSourceProperty);
        set => this.SetValue(ItemsSourceProperty, value);
    }

    public DataTemplate ItemTemplate
    {
        get => (DataTemplate)this.GetValue(ItemTemplateProperty);
        set => this.SetValue(ItemTemplateProperty, value);
    }

    private bool willUpdate = true;
    private void HandleItemChanged(object sender, NotifyCollectionChangedEventArgs eventArgs)
    {
        if (!willUpdate)
        {
            willUpdate = true;
            Device.BeginInvokeOnMainThread(Populate);
        }
    }

    public HorizontalScrollList()
    {
        this.Orientation = ScrollOrientation.Horizontal;
    }

    private void Populate()
    {
        willUpdate = false;

        Content = null;

        if (ItemsSource == null || ItemTemplate == null)
        {
            return;
        }

        var list = new StackLayout { Orientation = StackOrientation.Horizontal };

        foreach (var viewModel in ItemsSource)
        {
            var content = ItemTemplate.CreateContent();
            if (!(content is View) && !(content is ViewCell))
            {
                throw new Exception($"Invalid visual object {nameof(content)}");
            }

            var view = content is View ? content as View : ((ViewCell)content).View;
            view.BindingContext = viewModel;

            list.Children.Add(view);
        }

        if (list.Children.Count == 0)
        {
            list.Padding = 20;
            list.Children.Add(new Label
            {
                WidthRequest = (list as VisualElement).Width - 30,
                HorizontalOptions = new LayoutOptions(LayoutAlignment.Fill, true),
                VerticalOptions = new LayoutOptions(LayoutAlignment.Fill, true),
                HorizontalTextAlignment = TextAlignment.Center,
                VerticalTextAlignment = TextAlignment.Center,
                FontSize = 15,
               
            });
        }

        Content = list;
    }

【问题讨论】:

  • EditTextCommand 是 VM 的属性,而不是 DocumentData。 LIstView 中的每一行都绑定到一个 DocumentData 对象。如果要引用父 VM 上的属性,请参阅docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/…
  • 根据您的描述,很难确定哪些数据有效,哪些无效。请编辑您的问题,以更清楚地说明哪些特定元素导致了问题

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


【解决方案1】:

你想达到像下面的 GIF 一样的结果吗?

我不知道你设置的是哪种样式或背景色,我设置的是静态背景色。

这是我编辑后的布局。controls:HorizontalScrollList 是一张图片,所以我评论它。

我更改了TapGestureRecognizer中的命令

 <StackLayout Spacing="0">
        <!--Pictures-->
        <StackLayout VerticalOptions="Start" Spacing="0" >
            <!--<controls:HorizontalScrollList VerticalOptions="Start" HeightRequest="300" x:Name="carouselView"  ItemsSource="{Binding Results, Mode=TwoWay}">
                <controls:HorizontalScrollList.ItemTemplate>
                    <DataTemplate>
                        <Image Source="{Binding Results.FieldVisualData}" 
                                    Margin="5">
                            --><!--<Image.GestureRecognizers>
                                    <TapGestureRecognizer
                                        Command="{Binding HandlePreviewTapped, Source={x:Reference vm}}"
                                        CommandParameter="{Binding}"/>
                                </Image.GestureRecognizers>--><!--
                        </Image>
                    </DataTemplate>
                </controls:HorizontalScrollList.ItemTemplate>
            </controls:HorizontalScrollList>-->
        </StackLayout>

        <StackLayout  VerticalOptions="Start" BackgroundColor="White" Spacing="10">
            <!--DocumentData-->
            <Label Grid.Row="0" HorizontalOptions="CenterAndExpand" Text="Občanský průkaz" VerticalOptions="End" ></Label>
            <StackLayout BackgroundColor="Green"  VerticalOptions="FillAndExpand">
                <ListView x:Name="list" BackgroundColor="Red"
                    HasUnevenRows="True"
                    HorizontalOptions="CenterAndExpand"
                    VerticalOptions="CenterAndExpand"
                    VerticalScrollBarVisibility="Never"
                    CachingStrategy="RecycleElement"
                   ItemsSource="{Binding Results, Mode=TwoWay}"
                    SeparatorVisibility="Default"
                    SelectionMode="None">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <ViewCell>
                                <Grid  BackgroundColor="Beige" Padding="10" >
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="*"/>
                                        <ColumnDefinition Width="15*"/>
                                        <ColumnDefinition Width="*"/>
                                        <ColumnDefinition Width="12*"/>
                                        <ColumnDefinition Width="*"/>
                                    </Grid.ColumnDefinitions>
                                    <Label Grid.Column="1" Padding="0" Text ="{Binding FieldDescriptor}" HorizontalOptions="Start" BackgroundColor="Gray" HorizontalTextAlignment="Start"/>
                                    <Label Grid.Column="3" Padding="0" Text="{Binding FieldValue}" FontSize="Small" TextColor="#6781a3"  BackgroundColor="AliceBlue" HorizontalOptions="Start" HorizontalTextAlignment="Start">
                                        <Label.GestureRecognizers>
                                            <TapGestureRecognizer
                                                Command="{Binding BindingContext.EditTextCommand, Source={x:Reference Name=list}}"  
                                                CommandParameter="{Binding .}"
                                                
                                                
                                                />
                                        </Label.GestureRecognizers>
                                    </Label>
                                </Grid>
                            </ViewCell>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </StackLayout>
        </StackLayout>
    </StackLayout>

这是布局背景代码。我添加三个数据来做一个测试。

 public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            IEnumerable<DocumentData> data = new DocumentData[] { new DocumentData() { FieldDescriptor="test 1", FieldValue=1, FieldVisualData=1 } };
            data = data.Append(new DocumentData() { FieldDescriptor = "test 2", FieldValue = 2, FieldVisualData = 2 });
            data = data.Append(new DocumentData() { FieldDescriptor = "test 3", FieldValue = 3, FieldVisualData = 3 });

            this.BindingContext = new ResultPageViewModel(data);
        }
    }

这里是ResultPageViewModels 代码。

using Acr.UserDialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;

namespace XFormsListviewMvvm
{
    public class ResultPageViewModel : BaseViewModel
    {
        public ObservableCollection<DocumentData> Results { get; } = new ObservableCollection<DocumentData>();
        public ICommand EditTextCommand { get; }
        object param = "";
        public ResultPageViewModel(IEnumerable<DocumentData> data)
        {
            EditTextCommand = new Command<DocumentData>(async (key) => await EditTextAsync(key));
            Load(data);
        }

        public void Load(IEnumerable<DocumentData> data)
        {
            foreach (var result in data)
            {
                var detail = new DocumentData()
                {
                    FieldVisualData = result.FieldVisualData,
                    FieldDescriptor = result.FieldDescriptor,
                    FieldValue = result.FieldValue,
                };
                Results.Add(detail);

            }
        }

        public async Task EditTextAsync(DocumentData param)
        {
            PromptResult pResult = await UserDialogs.Instance.PromptAsync(new PromptConfig
            {
                InputType = InputType.Password,
                Text = param.FieldValue.ToString(),
                Title = "Insert your Password",
            });
            if (pResult.Ok)
            {
                param.FieldValue = pResult.Text;
            }
          
        }
    }
}

如果您需要更改值,则布局将显示它。您需要在DocumentData 中实现BaseViewModel

namespace XFormsListviewMvvm
{
    public class DocumentData:BaseViewModel
    {
    

        private object fieldVisualData = "Hello world";
        public object FieldVisualData
        {
            get => fieldVisualData;
            set => SetValue(ref fieldVisualData, value);
        }

        private object fieldValue = "Hello world";
        public object FieldValue
        {
            get => fieldValue;
            set => SetValue(ref fieldValue, value);
        }
        public object FieldDescriptor { get; internal set; }
    
    }
}

=============更新===================

我添加了您的controls:HorizontalScrollList 代码。我将 &lt;Image Source="{Binding Results.FieldVisualData}"&gt; 更改为 &lt;Image Source="{Binding FieldVisualData}" &gt;

这里是运行gif。图片可以正常看到了。

这是编辑后的布局。

 <StackLayout Spacing="0">
        <!--Pictures-->
        <StackLayout VerticalOptions="Start" Spacing="0" >
            <controls:HorizontalScrollList VerticalOptions="Start" HeightRequest="300" x:Name="carouselView"  ItemsSource="{Binding Results, Mode=TwoWay}">
                <controls:HorizontalScrollList.ItemTemplate>
                    <DataTemplate>
                        <Image Source="{Binding FieldVisualData}" 
                                    Margin="5">
                            <!--<Image.GestureRecognizers>
                                    <TapGestureRecognizer
                                        Command="{Binding HandlePreviewTapped, Source={x:Reference vm}}"
                                        CommandParameter="{Binding}"/>
                                </Image.GestureRecognizers>-->
                        </Image>
                    </DataTemplate>
                </controls:HorizontalScrollList.ItemTemplate>
            </controls:HorizontalScrollList>
        </StackLayout>

        <StackLayout  VerticalOptions="Start" BackgroundColor="White" Spacing="10">
            <!--DocumentData-->
            <Label Grid.Row="0" HorizontalOptions="CenterAndExpand" Text="Občanský průkaz" VerticalOptions="End" ></Label>
            <StackLayout BackgroundColor="Green"  VerticalOptions="FillAndExpand">
                <ListView x:Name="list" BackgroundColor="Red"
                    HasUnevenRows="True"
                    HorizontalOptions="CenterAndExpand"
                    VerticalOptions="CenterAndExpand"
                    VerticalScrollBarVisibility="Never"
                    CachingStrategy="RecycleElement"
                   ItemsSource="{Binding Results, Mode=TwoWay}"
                    SeparatorVisibility="Default"
                    SelectionMode="None">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <ViewCell>
                                <Grid  BackgroundColor="Beige" Padding="10" >
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="*"/>
                                        <ColumnDefinition Width="15*"/>
                                        <ColumnDefinition Width="*"/>
                                        <ColumnDefinition Width="12*"/>
                                        <ColumnDefinition Width="*"/>
                                    </Grid.ColumnDefinitions>
                                    <Label Grid.Column="1" Padding="0" Text ="{Binding FieldDescriptor}" HorizontalOptions="Start" BackgroundColor="Gray" HorizontalTextAlignment="Start"/>
                                    <Label Grid.Column="3" Padding="0" Text="{Binding FieldValue}" FontSize="Small" TextColor="#6781a3"  BackgroundColor="AliceBlue" HorizontalOptions="Start" HorizontalTextAlignment="Start">
                                        <Label.GestureRecognizers>
                                            <TapGestureRecognizer
                                                Command="{Binding BindingContext.EditTextCommand, Source={x:Reference Name=list}}"  
                                                CommandParameter="{Binding .}"
                                                
                                                
                                                />
                                        </Label.GestureRecognizers>
                                    </Label>
                                </Grid>
                            </ViewCell>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </StackLayout>
        </StackLayout>
    </StackLayout>

这是布局背景代码。

   public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            IEnumerable<DocumentData> data = new DocumentData[] { new DocumentData() { FieldDescriptor="test 1", FieldValue=1, FieldVisualData= "https://aka.ms/campus.jpg" } };
            data = data.Append(new DocumentData() { FieldDescriptor = "test 2", FieldValue = 2, FieldVisualData = "https://aka.ms/campus.jpg" });
            data = data.Append(new DocumentData() { FieldDescriptor = "test 3", FieldValue = 3, FieldVisualData = "https://aka.ms/campus.jpg" });

            this.BindingContext = new ResultPageViewModel(data);
        }
    }

【讨论】:

  • 嗨,谢谢,这看起来不错。但是我的主要问题是为什么我无法获取图片:D
  • 你是指controls:HorizontalScrollList中的图片吗?
  • 你能分享controls:HorizontalScrollList代码吗?
  • 谢谢,它成功了。我已经接受了答案,但感谢您在接受答案后继续帮助我。
猜你喜欢
  • 1970-01-01
  • 2010-10-28
  • 2020-04-19
  • 2021-03-11
  • 2017-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多