在ItemSource上引发属性更改事件不会触发AutoGeneratingColumn事件

时间:2019-03-12 03:52:25

标签: c# wpf datagrid inotifypropertychanged

我有以下代码;目的是在单击上下文菜单时引发AutoGeneratingColumn事件。

XAML

<UserControl x:Class="SyncTabControls.ExcelReport"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 

             xmlns:local="clr-namespace:SyncTabControls"
             xmlns:viewmodel="clr-namespace:SyncTabControls.ViewModel"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">

    <UserControl.DataContext>
        <viewmodel:ViewModel/>
    </UserControl.DataContext>

    <DataGrid x:Name="abcd" AutoGenerateColumns="True" AutoGeneratingColumn="abcd_AutoGeneratingColumn"  ItemsSource="{Binding OrderInfoCollection}" >
        <DataGrid.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Update"    Command="{Binding Path=PlacementTarget.DataContext.UpdateCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"></MenuItem>
            </ContextMenu>
        </DataGrid.ContextMenu>

    </DataGrid>

</UserControl>

<Window x:Class="SyncTabControls.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        xmlns:local="clr-namespace:SyncTabControls"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">

    <local:ExcelReport/>
</Window>

模型

public class Model : INotifyPropertyChanged
{
    int orderID;
    string customerId;
    string country;
    string customerName;
    string shippingCity;
    DateTime orderDate;


    public event PropertyChangedEventHandler PropertyChanged;
    public int OrderID
    {
        get { return orderID; }
        set { orderID = value; PropertyChanged?.Invoke(nameof(OrderID), new PropertyChangedEventArgs(nameof(OrderID))); }
    }

    public string CustomerID
    {
        get { return customerId; }
        set { customerId = value; PropertyChanged?.Invoke(nameof(CustomerID), new PropertyChangedEventArgs(nameof(CustomerID))); }
    }

    public string CustomerName
    {
        get { return customerName; }
        set { customerName = value; PropertyChanged?.Invoke(nameof(CustomerName), new PropertyChangedEventArgs(nameof(CustomerName))); }
    }

    public string Country
    {
        get { return country; }
        set { country = value; PropertyChanged?.Invoke(nameof(Country), new PropertyChangedEventArgs(nameof(Country))); }
    }

    public string ShipCity
    {
        get { return shippingCity; }
        set { shippingCity = value; PropertyChanged?.Invoke(nameof(ShipCity), new PropertyChangedEventArgs(nameof(ShipCity))); }
    }

    public DateTime OrderDate
    {
        get { return orderDate; }
        set { orderDate = value; PropertyChanged?.Invoke(nameof(OrderDate), new PropertyChangedEventArgs(nameof(OrderDate))); }
    }

    public Model(int orderId, string customerName, string country, string customerId, string shipCity)
    {
        this.OrderID = orderId;
        this.CustomerName = customerName;
        this.Country = country;
        this.CustomerID = customerId;
        this.ShipCity = shipCity;
        this.OrderDate = DateTime.Now;
    }

    public Model()
    {

    }
}

ViewModel

public class ViewModel : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;
    private BaseCommand updateCommand;
    public BaseCommand UpdateCommand
    {
        get
        {
            if (updateCommand == null)
                updateCommand = new BaseCommand(AutoGeneratingColEvents);
            return updateCommand;
        }
    }

    private void AutoGeneratingColEvents(object obj)
    {

        PropertyChanged?.Invoke(nameof(OrderInfoCollection), new PropertyChangedEventArgs(nameof(OrderInfoCollection)));  //the `AutoGeneratingColumn` event not fired.
    }

    ObservableCollection<Model.Model> orderCollection;
    public ObservableCollection<Model.Model> OrderInfoCollection
    {
        get { return orderCollection; }
        set { orderCollection = value; }
    }
    public ViewModel()
    {
        orderCollection = new ObservableCollection<Model.Model>();

        this.GenerateOrders();
        PropertyChanged?.Invoke(nameof(OrderInfoCollection), new PropertyChangedEventArgs(nameof(OrderInfoCollection)));
    }
    private void GenerateOrders()
    {
        orderCollection.Add(new Model.Model(1001, "Maria Anders", "Germany", "ALFKI", "Berlin"));
        orderCollection.Add(new Model.Model(1002, "Ana Trujilo", "Mexico", "ANATR", "México D.F."));
        orderCollection.Add(new Model.Model(1003, "Antonio Moreno", "Mexico", "ANTON", "México D.F."));
        orderCollection.Add(new Model.Model(1004, "Thomas Hardy", "UK", "AROUT", "London"));
        orderCollection.Add(new Model.Model(1005, "Christina Berglund", "Sweden", "BERGS", "Luleå"));
        orderCollection.Add(new Model.Model(1006, "Hanna Moos", "Germany", "BLAUS", "Mannheim"));
        orderCollection.Add(new Model.Model(1007, "Frédérique Citeaux", "France", "BLONP", "Strasbourg"));
        orderCollection.Add(new Model.Model(1008, "Martin Sommer", "Spain", "BOLID", "Madrid"));
        orderCollection.Add(new Model.Model(1009, "Laurence Lebihan", "France", "BONAP", "Marseille"));
        orderCollection.Add(new Model.Model(1010, "Elizabeth Lincoln", "Canada", "BOTTM", "Tsawassen"));
        orderCollection.Add(new Model.Model(1011, "Martin Sommer", "Spain", "BOLID", "Madrid"));
        orderCollection.Add(new Model.Model(1012, "Laurence Lebihan", "France", "BONAP", "Marseille"));
        orderCollection.Add(new Model.Model(1013, "Elizabeth Lincoln", "Canada", "BOTTM", "Tsawassen"));
        orderCollection.Add(new Model.Model(1014, "Martin Sommer", "Spain", "BOLID", "Madrid"));
        orderCollection.Add(new Model.Model(1015, "Laurence Lebihan", "France", "BONAP", "Marseille"));
        orderCollection.Add(new Model.Model(1016, "Elizabeth Lincoln", "Canada", "BOTTM", "Tsawassen"));
    }
}

我试图通过引发ItemSource ViewModel.OrderInfoCollection上的属性更改事件来实现这一目标,因为我认为这样做会通知datagrid,因此应该对其进行刷新(并且将引发AutoGeneratingColumn事件)。

但是事实并非如此!方法AuthoGeneratingColumn不会引发AutoGeneratingColEvents(object obj)事件。

如何强制数据网格触发AutoGeneratingColumn事件?

1 个答案:

答案 0 :(得分:0)

您传递给Invoke方法的第一个参数应该是对视图模型的引用:

private void AutoGeneratingColEvents()
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(OrderInfoCollection)));
}

您还需要重置AutoGeneratingColumn的源属性以再次引发:

private void AutoGeneratingColEvents()
{
    var orders = OrderInfoCollection;
    OrderInfoCollection = null;
    OrderInfoCollection = orders;
}

ObservableCollection<ExcelModel> orderCollection;
public ObservableCollection<ExcelModel> OrderInfoCollection
{
    get { return orderCollection; }
    set { orderCollection = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(OrderInfoCollection))); }
}