Listview binding doesn't update the view

2019-08-26 02:42发布

I have this setup for my ListView and I am trying to make Binding to work in my MVVM structure.

This is the xaml code:

<Window.Resources>
    <CollectionViewSource
        x:Key="DeviceList"
        Source="{Binding Path=DiscoveredDevicesList}">

    </CollectionViewSource>
</Window.Resources>
    <ListView
    Grid.Row="1" 
    Width="500"
    HorizontalAlignment="Left"
    Margin="10"
    Grid.Column="1"
    DataContext="{StaticResource DeviceList}"
    ItemsSource="{Binding}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Device name" DisplayMemberBinding="{Binding Path=DeviceName}"/>
                <GridViewColumn Header="Rssi" DisplayMemberBinding="{Binding Path=Rssi}"/>
                <GridViewColumn Header="GPS Row" DisplayMemberBinding="{Binding Path=GpsSignal}"/>
            </GridView>
        </ListView.View>
    </ListView>

And the following is the code to implement the binding

    //Constructor 
    public MainWindowViewModel()
    {
        DiscoveredDevicesList = new ObservableCollection<MyDeviceInfo>();
    }

    private ObservableCollection<MyDeviceInfo> _DiscoveredDevicesList;
    public ObservableCollection<MyDeviceInfo> DiscoveredDevicesList
    {
        get
        {
            return _DiscoveredDevicesList;
        }
        set
        {
            _DiscoveredDevicesList = value;
            OnPropertyChanged("DiscoveredDevicesList");
        }
    }

Using Add() and Clear() updates the view just fine when used as below:

        var client = new BluetoothClient();
        DiscoveredDevicesList.Clear();
        IEnumerable<MyDeviceInfo> csaDevices = null;
        csaDevices = await DiscoverCsaDevicesAsync(client);

        foreach (var csaDevice in csaDevices)
        {
            DiscoveredDevicesList.Add(csaDevice);
            DiscoveredDevicesList.First().GpsSignal = true;
        }

So I can see the value of GpsSignal as changed to ture from initial opposite in my view.

However, if I put the following same line in the OnClick of a button doesn't do the same and the value stays false since I am not using any Add() or Clear() and I simply rely on the OnPropertyChanged to do the trick for me.

            DiscoveredDevicesList.First().GpsSignal = true;

The rest of the bindings such as button clicks and textblock information work fine, then I would assume it shouldn't be the problem with implementation of the binding on the back of the stage.

Would appreciate your suggestions on this.

1条回答
霸刀☆藐视天下
2楼-- · 2019-08-26 03:36

if your MyDeviceInfo class implement INotifyPropertyChanged and your property GpsSignal raise OnPropertyChanged() you should see all changes when your bindings are right.

nevertheless i would change your code in this way:

remove CollectionViewSource from your resources and use simple binding

<Window.Resources>

</Window.Resources>
<ListView ItemsSource="{Binding DeviceList}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Device name" DisplayMemberBinding="{Binding Path=DeviceName}"/>
            <GridViewColumn Header="Rssi" DisplayMemberBinding="{Binding Path=Rssi}"/>
            <GridViewColumn Header="GPS Row" DisplayMemberBinding="{Binding Path=GpsSignal}"/>
        </GridView>
    </ListView.View>
</ListView>

set the datacontext for your window to your MainWindowViewModel in codebehind or xaml. instead of using OnClick, pls use ICommands (RelayCommand or DelegateCommand)

<Button Command="{Binding MyCommand4GpsSignalIsTrue}" />
查看更多
登录 后发表回答