简体   繁体   中英

How to correctly use DataBinding, INotifyPropertyChanged, ListViewGridView

I ran in an Issue trying to Get my BoundData Updated in WPF. My Data is shown but my UI does not React to Changes in the Data.

I have a XAML Class looking like this:

<Window x:Class="CSharpBoiler.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:util="clr-namespace:Wpf.Util"
    Title="MainWindow" Loaded="Window_Loaded" Closing="Window_Closing" Height="Auto" Width="Auto"
    DataContext="{Binding matchDataList, RelativeSource={RelativeSource Self}}">

<Grid>
    <ListView
  IsSynchronizedWithCurrentItem="True"
  util:GridViewSort.AutoSort="True"
  x:Name="MainListView" >
        <ListView.View>
            <GridView x:Name="MainGridView">
                <GridView.Columns>
                    <GridViewColumn Header="Demo, press to Download"
                            util:GridViewSort.PropertyName="Demo"
                            x:Name="DemoGridViewColumn">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <DockPanel>
                                    <ProgressBar x:Name="DemoButtonProgressbar" 
                                     Maximum="100" Minimum="0" 
                                     Value="{Binding AnalysisProgress,
                                     UpdateSourceTrigger=PropertyChanged}" Width="100"/>
                                </DockPanel>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView.Columns>
            </GridView>
        </ListView.View>
    </ListView>
</Grid>

MyMainWindow looks like this:

    public partial class MainWindow : Window
{
    private List<MatchData> matchDataList = new List<MatchData>();

    public MainWindow()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        MainListView.ItemsSource = matchDataList;
    }

In matchDataList is a number of MatchData objects which I want to represent in my ListViewGridView. MatchData looks like this:

public class MatchData : ObservableCollection<MatchData>, INotifyPropertyChanged
{
    public int _AnalysisProgress;
    public int AnalysisProgress
    {
        get { return _AnalysisProgress; }
        set
        {
            _AnalysisProgress = value;
            NotifyPropertyChanged("AnalysisProgress");
        }
    }

    public PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

}

At this point my Progressbar is displayed in my ListGridViewgridView construct. I change the Value of it in my code to show progress. When I change the value of AnalysisProgress NotifyPropertyChanged is called correctly. But PropertyChanged is always null.

Therefore no event is fired and the Value of the Progressbar isn't changing. When I refresh the UI by clicking on one of the column headers Progressbar shows the correct Value. Obviously I want to have my Progressbar show the current progress without clicking on it.

I'm quiet new to XAML Binding and hope that I didn't make to many fundamental mistakes, therefore I'm quite open to all other proposals in how to make this code better. I don't quite like how restricted I'm at accessing the items of the ListViewGridview construct, but it is the best table I found which has sorting by clicking on column headers.

正在运行的程序的图像,进度栏位于“分析”按钮的右侧

The Problem was in

public class MatchData : ObservableCollection<MatchData>, INotifyPropertyChanged

after changing it to

public class MatchData : INotifyPropertyChanged

VS offered me to implement the Interface, after doing so and fixing

    public PropertyChangedEventHandler PropertyChanged;

public void NotifyPropertyChanged(string propertyName)
{
    if (PropertyChanged != null)
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

to

        public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, e);
        }
    }

and

    public int _AnalysisProgress;
public int AnalysisProgress
{
    get { return _AnalysisProgress; }
    set
    {
        _AnalysisProgress = value;
        NotifyPropertyChanged("AnalysisProgress");
    }
}

to

        public int _AnalysisProgress { get; set; }
    public int AnalysisProgress
    {
        get { return _AnalysisProgress; }
        set
        {
            _AnalysisProgress = value;
            OnPropertyChanged(new PropertyChangedEventArgs("AnalysisProgress"));
        }
    }

Everything is running as it should.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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