Code Bye

wpf 自定义的DataGrid绑定的数据源增加了,UI没更新

 

我有一个自定义DataGrid控件

<ctl:MedPagedListView Margin="5,2" Style="{DynamicResource {x:Type DataGrid}}" Name="POListView" DockPanel.Dock="Top">
                <ctl:MedPagedListView.Columns>
                    <DataGridTextColumn Header="{DynamicResource GridHeaderPOName}" Binding="{Binding Name}" />
                    <DataGridTextColumn Header="{DynamicResource GridHeaderPOPath}" Binding="{Binding Path}" />
                </ctl:MedPagedListView.Columns>
            </ctl:MedPagedListView>

然后我给我的集合PermissionObjectDataList添加记录
,代码大概如下, poList.Add(data);
然后再绑定
POListView.PagedItemsSource = poList;     
记录是加进集合了,但是页面并没有更新。
PermissionObjectDataList 是继承ObservableCollection的。
如果我要UI更新的话必须先写POListView.PagedItemsSource = null,然后再写POListView.PagedItemsSource = poList; 才行,
为什么?
而我写了一个测试的工程,用的是ListBox控件
myListBox.DataContext = nameList;
当我给nameList增加记录时界面自动更新了。

#1

大哥,代码不完整。你的PagedItemsSource这个属性是DependencyProperty吗?把你自定义控件的关键代码也贴一下。

#2

是的,代码如下
public class MedPagedListView : DataGrid
    {
        public object PagedItemsSource
        {
            get { return (object)GetValue(PagedItemsSourceProperty); }
            set { SetValue(PagedItemsSourceProperty, value); }
        }

        // Using a DependencyProperty as the backing store for PagedItemsSource.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PagedItemsSourceProperty =
            DependencyProperty.Register("PagedItemsSource", typeof(object), typeof(MedPagedListView), new UIPropertyMetadata(null));
        

        public int PageSize
        {
            get { return (int)GetValue(PageSizeProperty); }
            set { SetValue(PageSizeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for PageSize.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PageSizeProperty =
            DependencyProperty.Register("PageSize", typeof(int), typeof(MedPagedListView), new UIPropertyMetadata(30));        

        public int CurrentPage
        {
            get { return (int)GetValue(CurrentPageProperty); }
            set { SetValue(CurrentPageProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CurrentPage.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CurrentPageProperty =
            DependencyProperty.Register("CurrentPage", typeof(int), typeof(MedPagedListView), new UIPropertyMetadata(0));

        public int TotalPage
        {
            get { return (int)GetValue(TotalPageProperty); }
            set { SetValue(TotalPageProperty, value); }
        }

        // Using a DependencyProperty as the backing store for TotalPage.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TotalPageProperty =
            DependencyProperty.Register("TotalPage", typeof(int), typeof(MedPagedListView), new UIPropertyMetadata(0));

        public int TotalRecords
        {
            get { return (int )GetValue(TotalRecordsProperty); }
            set { SetValue(TotalRecordsProperty, value); }
        }

        // Using a DependencyProperty as the backing store for TotalRecords.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TotalRecordsProperty =
            DependencyProperty.Register("TotalRecords", typeof(int), typeof(MedPagedListView), new UIPropertyMetadata(0));
             

        static MedPagedListView()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(MedPagedListView), new FrameworkPropertyMetadata(typeof(MedPagedListView)));
        }

        protected override void OnInitialized(EventArgs e)
        {
            base.OnInitialized(e);

            CommandBindings.Add(new CommandBinding(PagerCommand.Prev, Prev_Executed, CanExecute));
            CommandBindings.Add(new CommandBinding(PagerCommand.Next, Next_Executed, CanExecute));
            CommandBindings.Add(new CommandBinding(PagerCommand.First, First_Executed, CanExecute));
            CommandBindings.Add(new CommandBinding(PagerCommand.Last, Last_Executed, CanExecute));
        }

        public void CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        public void Prev_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            LoadPageData(CurrentPage - 1);
        }

        public void Next_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            LoadPageData(CurrentPage + 1);
        }
        public void First_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            LoadPageData(1);
        }
        public void Last_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            LoadPageData(TotalPage);
        }
        private void LoadPageData(int pageNo)
        {
            if (PagedItemsSource != null)
            {
                IEnumerable<Object> source = PagedItemsSource as IEnumerable<Object>;
                if (source != null)
                {
                    if (pageNo > TotalPage || pageNo < 1)
                    {
                        return;
                    }
                    int start = (pageNo -1) * PageSize;

                    IEnumerable<Object> result = source.Skip(start).Take(PageSize);
                    this.SetValue(DataGrid.ItemsSourceProperty, result);

                    CurrentPage = pageNo;
                }
            }
        }
        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            base.OnPropertyChanged(e);
            if (e.Property.Name == "PagedItemsSource")
            {

                if (PagedItemsSource != null)
                {
                    IEnumerable<Object> source = PagedItemsSource as IEnumerable<Object>;
                    double count = source.Count();
                    double pageSize = PageSize;
                    double pageCount = count / pageSize;

                    CurrentPage = 1;
                    TotalPage = Convert.ToInt32(Math.Ceiling(pageCount));
                    if (TotalPage == 0) TotalPage = 1;
                    TotalRecords = source.Count();
                    LoadPageData(CurrentPage);
                }
            }
        }
    }


    sealed class PagerCommand
    {
        private static RoutedUICommand prevCmd = new RoutedUICommand("Prev", "Prev", typeof(MedPagedListView));

        public static RoutedUICommand Prev
        {
            get { return PagerCommand.prevCmd; }
            set { PagerCommand.prevCmd = value; }
        }

        private static RoutedUICommand nextCmd = new RoutedUICommand("Next", "Next", typeof(MedPagedListView));

        public static RoutedUICommand Next
        {
            get { return PagerCommand.nextCmd; }
            set { PagerCommand.nextCmd = value; }
        }
        private static RoutedUICommand firstCmd = new RoutedUICommand("First", "First", typeof(MedPagedListView));

        public static RoutedUICommand First
        {
            get { return PagerCommand.firstCmd; }
            set { PagerCommand.firstCmd = value; }
        }
        private static RoutedUICommand lastCmd = new RoutedUICommand("Last", "Last", typeof(MedPagedListView));

        public static RoutedUICommand Last
        {
            get { return PagerCommand.lastCmd; }
            set { PagerCommand.lastCmd = value; }
        }

    }

#3

没有人吗????

#4

我看了下你的积分和你发帖问的好几个问题。虽然积分可有可无,但是这种发好多贴总分只有40,就让人根本不想继续下去了。

#5

列表项发生变化后需要通知 INotifyCollectionChanged,实现这个接口,或者找已经这个接口的类做为数据源,如 System.Collections.ObjectModel.ObservableCollection<T>,就可以实现数据项自动更新了。

#6

我这个数据源poList是实现System.Collections.ObjectModel.ObservableCollection<T>的,还有回复楼上,我每个问题都各自是40分阿.

#7

是我2了…
50分

#8

回复楼:

直接绑定后再code修改itemsource时界面数据不更新,除非拖动一下列宽或者单击一下表格等操作后才会更新。用grid.Invalidate()也没用。  除非就是和你说的一样先赋值null,再给list。

要实现自动更新的话,用MVVM模式的绑定,在vm中设置响应事件,当数据改变时响应UI的更新。

#9

回复8楼:

你真坑,说了跟没说一样

#10

回复9楼:

只要题主懂了就行。 你不知道这个问题当然看不懂。


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明wpf 自定义的DataGrid绑定的数据源增加了,UI没更新