简体   繁体   English

组合框值更改时,WPF MVVM更新数据网格

[英]WPF MVVM Update Datagrid when Combobox value changes

I have a WPF application with a datagrid that is populated based on a month and year. 我有一个WPF应用程序,其中包含一个基于月份和年份的数据网格。 Using the MVVM pattern, how do I update the datagrid when the user changes the month or year selected value? 使用MVVM模式,当用户更改月份或年份选定的值时,如何更新数据网格?

View 视图

<ComboBox DockPanel.Dock="Left" Name="comboBoxMonth" ItemsSource="{Binding Months}" SelectedItem="{Binding SelectedMonth}" TabIndex="0"></ComboBox>
<ComboBox DockPanel.Dock="Left" Name="comboBoxYear" ItemsSource="{Binding Years}" SelectedItem="{Binding SelectedYear}" TabIndex="0"></ComboBox>

<DataGrid AutoGenerateColumns="True" ItemsSource="{Binding BudgetEntries}"></DataGrid>

ViewModel 视图模型

public class BudgetEntryViewModel : INotifyPropertyChanged
{
    private FinancialManagement4MEContext context = new FinancialManagement4MEContext();
    private int _SelectedMonth = GetDefaultMonth();
    private ObservableCollection<int> _Years;
    private int _SelectedYear = GetDefaultYear();
    private ObservableCollection<BudgetEntry> _BudgetEntries;
    private static int GetDefaultMonth()
    {
        int _monthnumber = DateTime.Now.Month;

        if (_monthnumber == 1) { _monthnumber = 12; }
        else { _monthnumber--; }

        return _monthnumber;
    }

    private static int GetDefaultYear()
    {
        int _year = DateTime.Now.Year;

        if (DateTime.Now.Month == 1) { _year--; }

        return _year;
    }

    public BudgetEntryViewModel()
    {
        _BudgetEntries = new ObservableCollection<BudgetEntry>((from b in context.BudgetEntries
                                                                where b.Year == _SelectedYear & b.Month == _SelectedMonth
                                                                select b).ToList());
    }

    public ObservableCollection<int> Months
    {
        get
        {
            ObservableCollection<int> _months = new ObservableCollection<int>();

            for (int i = 1; i <= 12; i++)
            {
                _months.Add(i);
            }

            return _months;
        }
    }

    public int SelectedMonth
    {
        get 
        { 
            return _SelectedMonth; 
        }
        set 
        {
            if (_SelectedMonth != value)
            {
                _SelectedMonth = value;
                RaisePropertyChanged("SelectedMonth");
            }
        }
    }

    public ObservableCollection<int> Years
    {
        get
        {
            _Years = new ObservableCollection<int>(((from b in context.BudgetEntries
                                                     select b.Year).ToList<int>().Distinct()).ToList());

            if (DateTime.Now.Month == 2 && DateTime.Now.Year > _Years.Max())
            {
                _Years.Add(DateTime.Now.Year);
            }

            return _Years;
        }
    }

    public int SelectedYear
    {
        get
        {
            return _SelectedYear;
        }
        set
        {
            if (_SelectedYear != value)
            {
                _SelectedYear = value;
                RaisePropertyChanged("SelectedYear");
            }
        }
    }

    public ObservableCollection<BudgetEntry> BudgetEntries
    {
        get 
        {
            return _BudgetEntries;
        }
        set
        {
            _BudgetEntries = value;
        }
    }

    void RaisePropertyChanged(string prop)
    {
        if (PropertyChanged != null) 
        { 
            PropertyChanged(this, new PropertyChangedEventArgs(prop)); 
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

You can do it in set methods 您可以通过设置方法来完成

public int SelectedMonth
{
    get 
    { 
        return _SelectedMonth; 
    }
    set 
    {
        if (_SelectedMonth != value)
        {
             _SelectedMonth = value;
             RaisePropertyChanged("SelectedMonth");
             UpdateData(); // This private method updates BudgetEntries collection
        }
    }
}

Be aware, that this will block UI thread, so if you are doing some long opperation like DB query make sure to use asynchronous call 请注意,这将阻止UI线程,因此,如果您要进行长时间的操作(如数据库查询),请确保使用异步调用

For example Task 例如Task

private void UpdateData()
{
    IsBusy = true;
    Task.Factory.CreateNew(()=>LongDBQuery())
                .ContinueWith(t =>
                              {
                                   if(t.Exception != null)
                                   {
                                        //Show Error Message
                                        return;
                                   }
                                   BudgetEntries = t.Result;
                              }
                              , TaskScheduler.FromCurrentSynchronizationContext());

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

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