MVVM模式的主视图详细信息

时间:2015-09-17 04:47:44

标签: c# wpf mvvm

我有一个MVVM - 使用Entity Framework 6的WPF浏览器应用程序。 我试图选择一个supplierDataGrid行并在另一个数据网格中显示相关的产品。但它不起作用。当我选择一行时,应用程序会冻结。谢谢你的帮助!

ViewModelBase

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 T _selected;
    public T Selected
    {
        get {
            if(_selected != null)
            GetSub();
            return _selected; 
            }
        set { _selected = value; 
            OnPropertyChanged("Selected"); }
    }

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

    protected virtual void Save()
    {
        //return true;
    }
    protected virtual bool CanSave()
    {
        return true;
    }

    public ICommand DeleteCommand
    {
        get
        {
           // return removeCommand ?? (removeCommand = new RelayCommand(Delete,CanDelete));
            return removeCommand ?? (removeCommand = new RelayCommand(p => this.Delete(), p => this.CanDelete()));

        }
    }

    protected virtual void Delete()
    { }

    protected virtual bool CanDelete()
    {
        if (Selected != null)
            return true;
        else
            return false;
    }

    public ICommand GetSubCommand
    {
        get
        {
            return getSubCommand ?? (getSubCommand = new RelayCommand(p => this.GetSub(), p => this.CanGetSub()));
        }
    }

    protected virtual async Task GetSub()
    {
        await Task.Delay(0); 
    }


    protected virtual bool CanGetSub()
    {
        return true;
    }
}

视图模型

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();
    }
    protected override void Delete()
    {
        var id = Selected;
        var supp = (from s in ctx.foodSuppliers
                where s.idfoodSupplier == id.idfoodSupplier
                select s).SingleOrDefault();
        ctx.foodSuppliers.Remove(supp);
        ctx.SaveChanges();
        Collection.Remove(supp);
    }
    protected virtual bool CanDelete()
    {
        return true;
    }

     protected override async Task GetSub()
    {

        var supplier = Selected;
        var pro = await (from p in ctx.products
                         where p.supplier == supplier.idfoodSupplier
                         select p).ToListAsync();

        Products = pro;

    }

    private IList<product> _products;

    public IList<product> Products
    {
        get
        {

            return _products;

        }
        set
        {
            _products = value;
            OnPropertyChanged("Products");
        }
    }
}

视图

<DataGrid x:Name="dataGrid"
          Margin="5"
          ItemsSource="{Binding Collection}"
          AutoGenerateColumns="False"
          SelectedItem="{Binding Selected, Mode=TwoWay}"
          SelectionMode="Extended"
          SelectionUnit="FullRow">
    <DataGrid.Columns>
        <DataGridTextColumn x:Name="dataGridTextColumn"
                            Header="Supplier"
                            Binding="{Binding idfoodSupplier, UpdateSourceTrigger=PropertyChanged}"
                            Visibility="Hidden" />
        <DataGridTextColumn Header="Supplier"
                            Binding="{Binding supplier, UpdateSourceTrigger=PropertyChanged}" />
    </DataGrid.Columns>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <i:InvokeCommandAction Command="{Binding GetCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</DataGrid>
<Button Height="Auto"
        Width="Auto"
        Content="Delete"
        Command="{Binding DeleteCommand}" />

1 个答案:

答案 0 :(得分:0)

编辑:程序冻结,因为你有无限的递归。选择getter调用GetSub,调用getter选择它调用GetSub等等... 我建议你在Selected setter中调用GetSub,但可能还需要一些额外的重构。

提示:当somethig冻结时,在visual studio中暂停程序并查看callstack窗口。你会立即知道在这种情况下发生了什么。按下暂停按钮后,可能需要在“线程”窗口(Ctrl + Alt + H)中切换到主线程。