【问题标题】:How to fill GridView Async如何填充 GridView 异步
【发布时间】:2016-08-02 17:08:47
【问题描述】:

我有一个 Gridview,其中的列是 Combobox、Checkbox 等控件。 GridView 由数据库与实体框架绑定到对象列表,绑定使用 MVVM 模式。 有时,查询只带来很少的元素,因此,Gridview 上的加载很快,但有时查询带来超过 500 条记录,加载变得非常非常慢。 有什么办法可以逐条记录加载Gridview?

这是我的 Gridview 代码:

<telerik:RadGridView x:Name="dtgResumen" AutoGenerateColumns="False" CellEditEnded="dtgResumen_CellEditEnded" GridLinesVisibility="Both" ItemsSource="{Binding LstAvancesCuvs, Mode=TwoWay, IsAsync=True}" RowIndicatorVisibility="Collapsed" SelectionMode="Multiple" SelectionUnit="FullRow">
  <telerik:RadGridView.Columns>

    <telerik:GridViewComboBoxColumn x:Name="colEstatus" Width="1.4*" Header="ESTATUS" IsFilterable="False" Tag="0">
        <telerik:GridViewComboBoxColumn.CellTemplate>
            <DataTemplate>
                <telerik:RadComboBox HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SelectedIndex="{Binding EstatusCUV, Mode=TwoWay}" SelectionChanged="comboBox_SelectionChanged">
                    <telerik:RadComboBoxItem Content="Cancelada" Foreground="Red" />
                    <telerik:RadComboBoxItem Content="Activa" Foreground="Green" />
                </telerik:RadComboBox>
            </DataTemplate>
        </telerik:GridViewComboBoxColumn.CellTemplate>
    </telerik:GridViewComboBoxColumn>

    <telerik:GridViewDataColumn x:Name="colId" Width="Auto" DataMemberBinding="{Binding IdCUVExcel}" Header="ID" IsFilterable="False" IsReadOnly="True"/>

    <telerik:GridViewDataColumn x:Name="colMza" Width="Auto" DataMemberBinding="{Binding Manzana}" Header="MZA" IsFilterable="False" IsReadOnly="True"/>

    <telerik:GridViewDataColumn x:Name="colLot" Width="Auto" DataMemberBinding="{Binding Lote}" Header="LOT" IsFilterable="False" IsReadOnly="True"/>

    <telerik:GridViewDataColumn x:Name="colNo" Width="Auto" DataMemberBinding="{Binding NumeroExterior}" Header="No" IsFilterable="False" IsReadOnly="True"/>

    <telerik:GridViewDataColumn x:Name="colInt" Width="Auto" DataMemberBinding="{Binding NumeroInterior}" Header="INT" IsFilterable="False" IsReadOnly="True"/>

    <telerik:GridViewDataColumn x:Name="colEdif" Width="Auto" DataMemberBinding="{Binding Edificio}" Header="EDIF" IsFilterable="False" IsReadOnly="True"/>

    <telerik:GridViewDataColumn x:Name="colAvanceIndividual" Width="*" Background="{Binding ColorAvance}" DataMemberBinding="{Binding AvanceIndividual, Mode=TwoWay}" IsFilterable="True" IsReadOnly="True">
        <telerik:GridViewDataColumn.Header>
            <TextBlock Text="% Avance Individual" TextAlignment="Center" TextWrapping="Wrap" />
        </telerik:GridViewDataColumn.Header>
        <telerik:GridViewDataColumn.CellStyle>
            <Style TargetType="telerik:GridViewCell">
                <Setter Property="Foreground" Value="{Binding ColorAvance}" />
            </Style>
        </telerik:GridViewDataColumn.CellStyle>
    </telerik:GridViewDataColumn>

    <telerik:GridViewDataColumn x:Name="colDtu" DataMemberBinding="{Binding DTU, Mode=TwoWay}" Header="DTU" IsFilterable="False">
        <telerik:GridViewDataColumn.CellTemplate>
            <DataTemplate>
                <CheckBox HorizontalAlignment="Center" VerticalAlignment="Center" BorderThickness="5" Click="CheckBox_Click" IsChecked="{Binding DTU, Mode=TwoWay}" />
            </DataTemplate>
        </telerik:GridViewDataColumn.CellTemplate>
    </telerik:GridViewDataColumn>

    <telerik:GridViewDataColumn x:Name="colPC" Width="*" DataMemberBinding="{Binding PC, Mode=TwoWay}" IsFilterable="False" Tag="1"/>
    <telerik:GridViewDataColumn x:Name="colE" Width="*" DataMemberBinding="{Binding Estructura, Mode=TwoWay}" IsFilterable="False" Tag="1"/>
    <telerik:GridViewDataColumn x:Name="colIHS" Width="*" DataMemberBinding="{Binding IHS, Mode=TwoWay}" IsFilterable="False" Tag="1"/>
    <telerik:GridViewDataColumn x:Name="colIE" Width="*" DataMemberBinding="{Binding IE, Mode=TwoWay}" IsFilterable="False" Tag="1"/>
    <telerik:GridViewDataColumn x:Name="colIG" Width="*" DataMemberBinding="{Binding IGE, Mode=TwoWay}" IsFilterable="False" Tag="1"/>
    <telerik:GridViewDataColumn x:Name="colAlbanileria" Width="*" DataMemberBinding="{Binding Albañileria, Mode=TwoWay}" IsFilterable="False" Tag="1"/>
    <telerik:GridViewDataColumn x:Name="colAcabados" Width="*" DataMemberBinding="{Binding Acabados, Mode=TwoWay}" IsFilterable="False" Tag="1"/>
    <telerik:GridViewDataColumn x:Name="colCHC" Width="*" DataMemberBinding="{Binding CHC, Mode=TwoWay}" IsFilterable="False" Tag="1"/>
    <telerik:GridViewDataColumn x:Name="colELE" Width="*" DataMemberBinding="{Binding ELE, Mode=TwoWay}" IsFilterable="False" Tag="1"/>

  </telerik:RadGridView.Columns>
</telerik:RadGridView>

这是我的模型:

public class MainWindowViewModel : BindableBase
{
    private ObservableCollection<AvanceObra> _lstAvancesCuvs;
    public ObservableCollection<AvanceObra> LstAvancesCuvs
    {
        get { return _lstAvancesCuvs; }
        set
        {
            _lstAvancesCuvs = value;
            OnPropertyChanged();
        }
    }

    public MainWindowViewModel()
    {
        _lstAvancesCuvs = new ObservableCollection<AvanceObra>();
    }
}

【问题讨论】:

  • 由于 Telerik 组件已绑定到模型,我认为这是不可能的(一一带来记录)。您可以尝试配置 GridView 以分页结果。或者,您可以摆脱 MVVM 绑定并按需在代码中加载数据。
  • 有什么办法可以优化数据加载吗?不一定要一个一个的
  • 当然,你也必须异步填充 DataSource ...
  • @Richard:你为什么不分页,这样数据会被分页,这将是某种惰性行为,这样会更快。
  • @lok​​usking,我试过但没用,可能是我做错了

标签: c# wpf entity-framework gridview mvvm


【解决方案1】:

这是一个非常简单的示例,说明如何异步处理您的操作:

XAML 片段

<StackPanel >
        <Button Content="FillData" Click="ButtonBase_OnClick"></Button>
        <ListView ItemsSource="{Binding Files, Mode=OneWay, IsAsync=True}"></ListView>
    </StackPanel>

代码

public partial class Window1 
    {
        private object _lock = new object();
        public Window1()
        {
            InitializeComponent();
            BindingOperations.EnableCollectionSynchronization(this.Files, this._lock);

            this.DataContext = this;
        }

        public ObservableCollection<string> Files => this._files;

        private ObservableCollection<string> _files = new ObservableCollection<string>();

        private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            await Task.Run(() =>
            {
                foreach (var file in Directory.GetFiles(yourPath)
                {
                    this.Files.Add(file);
                }
            });
        }
    }

我这样做又快又脏,这就是代码隐藏的原因。

注意BindingOperations.EnableCollectionSynchronization(this.Files, this._lock);

这使异步机制能够从另一个线程更新您的集合。应该是这样的。

玩得开心

【讨论】:

  • 非常感谢,我去试试!
  • 你能解释一下吗?例外? Gui-Freeze?
  • @lok​​using 主要是GUI-Freeze。抱歉缺席
  • 尝试从LstAvancesCuvs 中删除setter。通过.Clear().Add() 更新您的值。设置整个集合大多会破坏绑定,这可能会导致您描述的副作用
猜你喜欢
  • 2019-11-02
  • 2018-08-11
  • 2017-07-26
  • 2017-12-19
  • 1970-01-01
  • 2013-04-13
  • 2018-10-16
  • 2015-07-23
  • 2011-05-15
相关资源
最近更新 更多