WPF-MVVM 数据网格的 ComboBoxColumn 问题

ComboBoxColumn Issue with WPF-MVVM datagrid

我想在我的数据网格 "Product" 中添加一个包含供应商列表的 ComboBox 列。但我所做的一切都不起作用。绑定此列的好方法是什么?

模特们:

 public partial class foodSupplier
    {
        public foodSupplier()
        {
            this.products = new HashSet<product>();
        }

        public int idfoodSupplier { get; set; }
        public string supplier { get; set; }

        public virtual ICollection<product> products { get; set; }
    }

public partial class product
    {
        public int idproduct { get; set; }
        public string @ref { get; set; }
        public int supplier { get; set; }
        public string refsup { get; set; }
        public string description { get; set; }
        public int MOQ { get; set; }
        public int unit { get; set; }
        public decimal priceMOQ { get; set; }

        public virtual foodSupplier foodSupplier { get; set; }
        public virtual unit unit1 { get; set; }
    }

这是我的命令库(ViewModel):

public class CommandBase<T> :INotifyPropertyChanged
        {
            #region "INotifyPropertyChanged members"

            public event PropertyChangedEventHandler PropertyChanged;
            //This routine is called each time a property value has been set. 
            //This will //cause an event to notify WPF via data-binding that a change has occurred. 
            protected void OnPropertyChanged(string propertyName)
            {
                var handler = PropertyChanged;
                if (handler != null)
                {
                    handler(this, new PropertyChangedEventArgs(propertyName));
                }
            }

            #endregion

            private ObservableCollection<T> collection;
            public ObservableCollection<T> Collection
            {
                get
                {
                    if (collection == null)
                    {
                        collection = new ObservableCollection<T>();
                    }
                    return collection;
                }
                set { collection = value; OnPropertyChanged("Collection");}
            }


            private ICommand getCommand;
            private ICommand saveCommand;
            private ICommand removeCommand;

            public ICommand GetCommand
            {
                get
                {
                    return getCommand ?? (getCommand = new RelayCommand(param => Get(),param=>CanGet()));
                }
            }
            protected virtual bool CanGet()
            {
                return true;
            }

            public ICommand SaveCommand
            {
                get
                {
                    return saveCommand ?? (saveCommand = new RelayCommand(param => Save()));
                }
            }
            protected virtual bool CanSave()
            {
                return true;
            }

            public ICommand DeleteCommand
            {
                get
                {
                    return removeCommand ?? (removeCommand = new RelayCommand(param=>Delete()));
                }
            }
            protected virtual bool CanDelete()
            {
                return true;
            }
    }

这里是 ProductViewModel:

    public class ProductViewModel : CommandBase<product>
        {
            public Context ctx = new Context();

            protected override void Get()
            {
                ctx.products.ToList().ForEach(supplier => ctx.products.Local.Add(supplier));
                Collection = ctx.products.Local;
            }
            protected override bool CanGet()
            {
                return true;
            }
            protected override void Save()
            {
                foreach (product item in Collection)
                {
                    if (ctx.Entry(item).State == System.Data.Entity.EntityState.Added)
                    {
                        ctx.products.Add(item);
                    }
                }
                ctx.SaveChanges();
            }
        }
}

这里是 SupplierViewModel:

public class SupplierViewModel : CommandBase<foodSupplier>
    {
        public Context ctx = new Context();

        protected override void Get()
        {
            ctx.foodSuppliers.ToList().ForEach(supplier => ctx.foodSuppliers.Local.Add(supplier));
            Collection = ctx.foodSuppliers.Local;
        }
        protected override bool CanGet()
        {
            return true;
        }
        protected override void Save()
        {
            foreach (foodSupplier item in Collection)
            {
                if (ctx.Entry(item).State == System.Data.Entity.EntityState.Added)
                {
                    ctx.foodSuppliers.Add(item);
                }
            }
            ctx.SaveChanges();
        }
}

这里的观点:

<Page.Resources>
        <vm:ProductViewModel x:Key="product"/>
        <vm:SupplierViewModel x:Key="supplier"/>
    </Page.Resources>

    <Grid DataContext="{Binding Source={StaticResource product}}">
        <StackPanel Grid.ColumnSpan="2" Margin="0,0,58,0">
            <Button  x:Name="BtnDelete"
                Content="Delete" 
                Command="{Binding DeleteCommand}"/>
            <Button  x:Name="BtnAdd" 
                Content="Save" 
                Command="{Binding SaveCommand}"/>
            <DataGrid x:Name="dataGrid" Margin="5"  ItemsSource="{Binding Collection}" AutoGenerateColumns="False">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="id" Binding="{Binding idproduct, UpdateSourceTrigger=PropertyChanged}" Visibility="Hidden"/>
                    <DataGridTextColumn Header="Ref FTHK" Binding="{Binding ref, UpdateSourceTrigger=PropertyChanged}" />
          <DataGridComboBoxColumn Header="Supplier" ItemsSource="{Binding Collection, Source={StaticResource supplier}}????" DisplayMemberPath="supplier" SelectedValueBinding="{Binding ????}" SelectedValuePath="idSupplier"/>
                    <DataGridTextColumn Header="Ref Supplier" Binding="{Binding refsup, UpdateSourceTrigger=PropertyChanged}"/>
                    <DataGridTextColumn Header="Description" Binding="{Binding description, UpdateSourceTrigger=PropertyChanged}"/>
                    <DataGridTextColumn Header="MOQ" Binding="{Binding MOQ, UpdateSourceTrigger=PropertyChanged}"/>
                    <DataGridTextColumn Header="Unit" Binding="{Binding unit, UpdateSourceTrigger=PropertyChanged}"/>
                    <DataGridTextColumn Header="Prix/MOQ" Binding="{Binding priceMOQ, UpdateSourceTrigger=PropertyChanged}"/>
                </DataGrid.Columns>
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Loaded">
                        <i:InvokeCommandAction Command="{Binding GetCommand}" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </DataGrid>
        </StackPanel>
    </Grid>

您必须像加载产品一样加载 SupplierCollection。我更喜欢随需应变的概念。类似于下面的代码

public class CommandBase<T> : INotifyPropertyChanged
{
    #region "INotifyPropertyChanged members"

    public event PropertyChangedEventHandler PropertyChanged;
    //This routine is called each time a property value has been set. 
    //This will //cause an event to notify WPF via data-binding that a change has occurred. 
    protected void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #endregion

    private ObservableCollection<T> collection;
    public ObservableCollection<T> Collection
    {
        get
        {
            if (collection == null)
            {
                Get();
            }
            return collection;
        }
        set { collection = value; OnPropertyChanged("Collection"); }
    }


    private ICommand getCommand;
    private ICommand saveCommand;
    private ICommand removeCommand;

    public ICommand GetCommand
    {
        get
        {
            return getCommand ?? (getCommand = new RelayCommand(Get, CanGet));
        }
    }
    protected virtual bool CanGet()
    {
        return true;
    }

    protected virtual void Get()
    {
        //return true;
    }

    //public ICommand SaveCommand
    //{
    //    get
    //    {
    //        return saveCommand ?? (saveCommand = new RelayCommand(param => Save()));
    //    }
    //}
    protected virtual bool CanSave()
    {
        return true;
    }

    //public ICommand DeleteCommand
    //{
    //    get
    //    {
    //        return removeCommand ?? (removeCommand = new RelayCommand(param => Delete()));
    //    }
    //}
    protected virtual bool CanDelete()
    {
        return true;
    }
}

现在您的视图将是这样的。

<Page.Resources>
    <vm:ProductViewModel x:Key="product"/>
    <vm:SupplierViewModel x:Key="supplier"/>
    <DataTemplate x:Key="SupplierDataTemplate">
        <TextBlock Text="{Binding supplier}"/>
    </DataTemplate>
</Page.Resources>
<Grid>
    <StackPanel>
        <Grid DataContext="{Binding Source={StaticResource product}}" x:Name="ProductGrid">
            <StackPanel Grid.ColumnSpan="2" Margin="0,0,58,0">
                <Button  x:Name="BtnDelete"
            Content="Delete" 
            Command="{Binding DeleteCommand}"/>
                <Button  x:Name="BtnAdd" 
            Content="Save" 
            Command="{Binding SaveCommand}"/>
                <DataGrid x:Name="dataGrid" Margin="5"  ItemsSource="{Binding Collection}" AutoGenerateColumns="False">
                    <DataGrid.Columns>
                        <DataGridTextColumn Header="id" Binding="{Binding idproduct, UpdateSourceTrigger=PropertyChanged}" Visibility="Hidden"/>
                        <DataGridTextColumn Header="Ref FTHK" Binding="{Binding ref, UpdateSourceTrigger=PropertyChanged}" />
                        <DataGridComboBoxColumn Header="Supplier" ItemsSource="{Binding Collection, Source={StaticResource supplier}}"
                                                DisplayMemberPath="supplier" 
                                                 SelectedValueBinding="{Binding supplier}"/>
                        <DataGridTextColumn Header="Ref Supplier" Binding="{Binding refsup, UpdateSourceTrigger=PropertyChanged}"/>
                        <DataGridTextColumn Header="Description" Binding="{Binding description, UpdateSourceTrigger=PropertyChanged}"/>
                        <DataGridTextColumn Header="MOQ" Binding="{Binding MOQ, UpdateSourceTrigger=PropertyChanged}"/>
                        <DataGridTextColumn Header="Unit" Binding="{Binding unit, UpdateSourceTrigger=PropertyChanged}"/>
                        <DataGridTextColumn Header="Prix/MOQ" Binding="{Binding priceMOQ, UpdateSourceTrigger=PropertyChanged}"/>
                    </DataGrid.Columns>
                    <!--<i:Interaction.Triggers>
                        <i:EventTrigger EventName="Loaded">
                            <i:InvokeCommandAction Command="{Binding GetCommand}" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>-->
                </DataGrid>
            </StackPanel>
        </Grid>

    </StackPanel>
</Grid>

希望对您有所帮助