简体   繁体   English

尽管修改了 Itemsource,MVVM ListView 仍未更新 | XAMARIN.FORMS, ANDROID

[英]MVVM ListView not updating despite Itemsource modification | XAMARIN FORMS, ANDROID

I would like to create an android Bluetooth scanner.我想创建一个 android 蓝牙扫描仪。 But I can't manage to display anything using a listview.但是我无法使用列表视图来显示任何内容。 I've tried debugging it for an extended amount of time without success.我试过长时间调试它但没有成功。 It seems like the problem doesn't come from the Bluetooth segments.问题似乎不是来自蓝牙部分。 But rather comes from a refreshing/binding issue.而是来自一个令人耳目一新/具有约束力的问题。

I'm debugging on a physical Android device, the permissions stuff should be ok since the devices list is updating but the linked list view isn't.我在物理 Android 设备上调试,权限应该没问题,因为设备列表正在更新,但链接列表视图没有。

It might be worth mentioning that I've started from the visual studio 2019 Xamarin flyout template.可能值得一提的是,我是从 visual studio 2019 Xamarin 弹出模板开始的。 Which, uses an app shell to navigate between the pages.其中,使用应用程序 shell 在页面之间导航。 I feel like the problem could also come from this since the app shell might mess with the view models links.我觉得问题也可能来自于此,因为应用程序 shell 可能会混淆视图模型链接。

PS: I am relatively new to MVVM. PS:我对 MVVM 比较陌生。

Any help would be appreciated !!任何帮助,将不胜感激 !!

I have the following code:我有以下代码:

ItemPage (.XAML)项目页面 (.XAML)

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="clavier.Views.ItemsPage"
                 Title="Devices"
                 x:Name="BrowseItemsPage">
    
        <ContentPage.Content>
            <StackLayout>
                <Button Text="Search" Command="{Binding SearchDeviceCommand}"/>
                <ListView x:Name="DevicesList"
                          ItemsSource="{Binding list, Mode=OneWay}"
                          IsPullToRefreshEnabled="True"
                          CachingStrategy="RecycleElement">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <ViewCell>
                                <StackLayout>
                                    <Label Text="{Binding NativeDevice.Name}"></Label>
                                    <Label Text="{Binding NativeDevice.Address}" ></Label>
                                </StackLayout>
                            </ViewCell>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
                <Button Text="End"/>
            </StackLayout>
        </ContentPage.Content>
    </ContentPage>

ItemPage code (.XAML.CS)项目页面代码 (.XAML.CS)

namespace clavier.Views
    {
        public partial class ItemsPage : ContentPage
        {
            public ItemsPage()
            {
                BindingContext = new ItemsViewModel();
                InitializeComponent();
            }
        }
    }

ViewModel (.CS)视图模型 (.CS)

    ```
    namespace clavier.ViewModels
    {
        public class ItemsViewModel : BaseViewModel
        {
            public IAdapter adapter;
            public IBluetoothLE bluetoothBLE;
            public IDevice SelectedDevice { get; set; }
            public string Title { get; set; }
            public ObservableCollection<IDevice> list { get; set; }
            public Command SearchDeviceCommand { get; }
    
            public ItemsViewModel()
            {
                bluetoothBLE = CrossBluetoothLE.Current;
                adapter = CrossBluetoothLE.Current.Adapter;
                SearchDeviceCommand = new Command(SearchDevice);
                list = new ObservableCollection<IDevice>();
            }
    
            public async void SearchDevice()
            {
                if (bluetoothBLE.State == BluetoothState.Off)
                {
                    await Shell.Current.DisplayAlert("Attention", "le bluetooth n'est pas activé.", "OK");
                } 
                else 
                {
                    list.Clear();
                    adapter.ScanTimeout = 10000;
                    adapter.ScanMode = ScanMode.Balanced;
                    adapter.DeviceDiscovered += (obj, a) =>
                    {
                        if (!list.Contains(a.Device))
                        {
                            list.Add(a.Device);
                        }
                    };
                    await adapter.StartScanningForDevicesAsync();
                }
            }
    
            public async void DevicesList_OnItemSelected()
            {
                var resullt = await Shell.Current.DisplayAlert("Alerte", "Vous êtes sur le point de vous connecter à cet appareil. Etes vosu sur de vouloir vous connecter ?","Se connecter", "Annuler");
    
                if (!resullt)
                {
                    return;
                }
                await adapter.StopScanningForDevicesAsync();
    
                try
                {
                    await adapter.ConnectToDeviceAsync(SelectedDevice);
                    await Shell.Current.DisplayAlert("Connection ...", "Status : " + SelectedDevice.State, "Ok");
                }
                catch (DeviceConnectionException ex)
                {
                    await Shell.Current.DisplayAlert("Erreur !", ex.Message, "Ok");
                }
            }
        }
    }
```

My app shell (.XAML)我的应用程序 shell (.XAML)

```
<?xml version="1.0" encoding="UTF-8"?>
<Shell xmlns="http://xamarin.com/schemas/2014/forms" 
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:local="clr-namespace:clavier.Views"
       Title="clavier"
       x:Class="clavier.AppShell">

    <Shell.Resources>
        <ResourceDictionary>
            <Style x:Key="BaseStyle" TargetType="Element">
                <Setter Property="Shell.BackgroundColor" Value="{StaticResource Primary}" />
                <Setter Property="Shell.ForegroundColor" Value="White" />
                <Setter Property="Shell.TitleColor" Value="White" />
                <Setter Property="Shell.DisabledColor" Value="#B4FFFFFF" />
                <Setter Property="Shell.UnselectedColor" Value="#95FFFFFF" />
                <Setter Property="Shell.TabBarBackgroundColor" Value="{StaticResource Primary}" />
                <Setter Property="Shell.TabBarForegroundColor" Value="White"/>
                <Setter Property="Shell.TabBarUnselectedColor" Value="#95FFFFFF"/>
                <Setter Property="Shell.TabBarTitleColor" Value="White"/>
            </Style>
            <Style TargetType="TabBar" BasedOn="{StaticResource BaseStyle}" />
            <Style TargetType="FlyoutItem" BasedOn="{StaticResource BaseStyle}" />

            <Style Class="FlyoutItemLabelStyle" TargetType="Label">
                <Setter Property="TextColor" Value="White"></Setter>
            </Style>
            <Style Class="FlyoutItemLayoutStyle" TargetType="Layout" ApplyToDerivedTypes="True">
                <Setter Property="VisualStateManager.VisualStateGroups">
                    <VisualStateGroupList>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal">
                                <VisualState.Setters>
                                    <Setter Property="BackgroundColor" Value="{x:OnPlatform UWP=Transparent, iOS=White}" />
                                    <Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="{StaticResource Primary}" />
                                </VisualState.Setters>
                            </VisualState>
                            <VisualState x:Name="Selected">
                                <VisualState.Setters>
                                    <Setter Property="BackgroundColor" Value="{StaticResource Primary}" />
                                </VisualState.Setters>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateGroupList>
                </Setter>
            </Style>

            <Style Class="MenuItemLayoutStyle" TargetType="Layout" ApplyToDerivedTypes="True">
                <Setter Property="VisualStateManager.VisualStateGroups">
                    <VisualStateGroupList>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal">
                                <VisualState.Setters>
                                    <Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="{StaticResource Primary}" />
                                </VisualState.Setters>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateGroupList>
                </Setter>
            </Style>
        </ResourceDictionary>
    </Shell.Resources>

    <FlyoutItem Title="Clavier bluetooth" Icon="icon_about.png">
        <ShellContent Route="AboutPage" ContentTemplate="{DataTemplate local:AboutPage}" />
    </FlyoutItem>
    <FlyoutItem Title="Information" Icon="icon_feed.png">
        <ShellContent Route="ItemsPage" ContentTemplate="{DataTemplate local:ItemsPage}" />
    </FlyoutItem>

    <MenuItem Text="Logout" StyleClass="MenuItemLayoutStyle" Clicked="OnMenuItemClicked">
    </MenuItem>

    <TabBar>
        <ShellContent Route="LoginPage" ContentTemplate="{DataTemplate local:LoginPage}" />
    </TabBar> 
</Shell>
```

During debugging, I've checked the XAML linker errors but I don't have anything.在调试过程中,我检查了 XAML linker 错误,但我什么都没有。 I've also tried step-by-step debugging and the list is correctly updating with the devices.我还尝试了逐步调试,并且列表正确地随设备更新。

I've also tried to add the INotifyProprietyChanged as it was suggested in other answers but nothing changed.我还尝试按照其他答案中的建议添加 INotifyProprietyChanged 但没有任何改变。 (I might have incorrectly used it) (我可能用错了)

Note: I'm using the plugin BLE nuget, and I've followed the instructions from the Git and from tutorials I've found on the web ( this one , and this one ).注意:我使用的是插件 BLE nuget,我已经按照Git和我在 web 上找到的教程( 这个还有这个)中的说明进行操作。

Thanks for your help @ColeX and @Jason.感谢@ColeX 和@Jason 的帮助。 I've figured out what was happening.我已经弄清楚发生了什么事。 I don't know how could I've not thought about this earlier.我不知道我怎么可能没有早点想到这个。

It appears that the default text color for my ListView was white which explains why I could not see anything.看来我的ListView的默认文本颜色是白色,这解释了为什么我看不到任何东西。

I don't know why by default the text and the background colors were the same but yeah that was the problem...我不知道为什么默认情况下文本和背景 colors 是相同的,但是是的,这就是问题所在......

From source code I see IDevice.NativeDevice is just an object , so maybe it can't recognize NativeDevice.Name in the binding with the Label.Text .从源代码中我看到IDevice.NativeDevice只是一个object ,所以它可能无法识别与Label.Text绑定的NativeDevice.Name

Can you try this code first?你能先试试这段代码吗?

<ViewCell>
   <StackLayout>
      <Label Text="{Binding Name}"></Label>
      <Label Text="{Binding NativeDevice}" ></Label>
   </StackLayout>
</ViewCell>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM