C# WPF UserControl命令绑定未使用UI MVVM

C# WPF UserControl命令绑定未使用UI MVVM,c#,wpf,mvvm,user-controls,C#,Wpf,Mvvm,User Controls,我有WindowClientSwindow和它的视图模型类ClientsViewModel。在ViewModel中,我定义了属性客户端并将其绑定到DataGrid的itemssource属性: private ObservableCollection<tblClient> clients; public ObservableCollection<tblClient> Clients { get { return clients; } set {

我有WindowClientSwindow和它的视图模型类ClientsViewModel。在ViewModel中,我定义了属性客户端并将其绑定到DataGrid的itemssource属性:

private ObservableCollection<tblClient> clients;
public ObservableCollection<tblClient> Clients
{
    get { return clients; }
    set
    {
        clients = value;
        OnPropertyChanged("Clients");
    }
}
我试图将命令从窗口的viewmodel绑定到此命令,因此我这样做:

private ICommand _cmdChangedIndex;
    public ICommand cmdChangedIndex
    {
        get
        {
            if (_cmdChangedIndex == null)
            {
                _cmdChangedIndex = new DelegateCommand(delegate()
                {
                    worker.DoWork += worker_FilterClientsList;
                    worker.RunWorkerCompleted += worker_FilterClientListCompleted;
                    worker.RunWorkerAsync();

                });
            }
            return _cmdChangedIndex;
        }
    }

    private void worker_FilterClientsList(object sender, DoWorkEventArgs e)
    {
        try
        {
            ServiceClient wcf = new ServiceClient();
            Clients = new ObservableCollection<tblClient>(wcf.FilterClients(PageIndex, PageSize));
            TotalCount = wcf.ReturnClientsCount();
        }
        catch (Exception ex)
        {

        }
    }

    private void worker_FilterClientListCompleted(object sender, RunWorkerCompletedEventArgs e) 
    {
        worker.DoWork -= worker_FilterClientsList;
    }
数据网格绑定:

<DataGrid IsReadOnly="True"  Name="dgClients" AutoGenerateColumns="False" ItemsSource="{Binding Path=Clients, UpdateSourceTrigger=PropertyChanged}">
     <DataGrid.Columns>
                ....
     </DataGrid.Columns>
</DataGrid>

只是一个想法,但看起来您正在ICommand中使用BackgroundWorker类?在worker_FilterClientsList方法中,您正在设置客户端可观察集合属性。我认为您无法从DoWork内部操纵UI,因为它运行在不同的线程上。尝试删除Try..catch块以查看它是否隐藏了这样的错误


通常,您必须从RunWorkerCompleted委托您的worker\u FilterClient ListCompleted方法更新UI。

好的,因此从您的问题、答案和许多评论来看,您的问题似乎是不可重现的。这意味着,只要解决问题,你就只能靠自己了。然而,这并不像听起来那么糟糕

由于显示的代码没有明显的问题,我无法指出错误所在。然而,我可以让你走上正确的道路来解决你自己的问题。这需要你付出一些时间和努力,但“没有痛苦。。。正如他们所说,没有收获

在一个复杂的项目中发现问题的最好方法之一就是在一个新的空项目中简化它。通常在执行此操作时,会发生以下两种情况之一:要么找出问题所在,要么创建一个简明的工作示例来演示您的问题,然后您可以将其作为新问题发布在此处,或者替代当前代码。这通常是一个双赢的局面

碰巧,StackOverflow帮助中心有一个页面可以帮助您完成此操作。请按照页面中的建议来帮助您简化问题


我想说的最后一点是,通常在应用程序中,数据访问层与UI是分开的。如果您像这样分离不同的关注点,您还会发现它进一步简化了情况。

确保正确实现了OnPropertyChanged方法。。。你能展示一下吗?我用代码更新了这个问题。这个代码在单独的类中,我在我的所有视图模型类中继承它。这个实现看起来也很好。。。你在别的地方有问题。告诉我。。。如果你打电话给客户会发生什么;何时调用ICommand?如果UI中没有发生任何事情,但集合被清空,那么您在通知UI更改时就会遇到问题。这正是发生的情况。我的集合是空的,再次调试时,一切似乎都很好,但UI保持不变。我想问题可能出在我的背景员工身上,所以我试着打电话给PropertyChanged;再次在RunWorkerCompleted事件中,但未成功。我也尝试了没有背景工作者的代码,但效果是一样的。谢谢你的回答,是的,我知道,我也尝试了你的建议,但我的UI仍然是一样的…谢谢你给我提供的所有帮助和提示。我会尽我所能解决这个烦人的问题。我解决了我的问题,在尽我所能没有成功之后,我只是从解决方案中删除了我的UC并再次添加了xaml。。。虽然很愚蠢,但还是完成了任务。
private ICommand _cmdChangedIndex;
    public ICommand cmdChangedIndex
    {
        get
        {
            if (_cmdChangedIndex == null)
            {
                _cmdChangedIndex = new DelegateCommand(delegate()
                {
                    worker.DoWork += worker_FilterClientsList;
                    worker.RunWorkerCompleted += worker_FilterClientListCompleted;
                    worker.RunWorkerAsync();

                });
            }
            return _cmdChangedIndex;
        }
    }

    private void worker_FilterClientsList(object sender, DoWorkEventArgs e)
    {
        try
        {
            ServiceClient wcf = new ServiceClient();
            Clients = new ObservableCollection<tblClient>(wcf.FilterClients(PageIndex, PageSize));
            TotalCount = wcf.ReturnClientsCount();
        }
        catch (Exception ex)
        {

        }
    }

    private void worker_FilterClientListCompleted(object sender, RunWorkerCompletedEventArgs e) 
    {
        worker.DoWork -= worker_FilterClientsList;
    }
<pc:GridPaging PageIndex="{Binding PageIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                       PageSize="{Binding PageSize, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                       TotalCount="{Binding TotalCount, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                       HorizontalAlignment="Center" x:Name="clientsPagingControl"
                       ChangedIndexCommand="{Binding cmdChangedIndex, UpdateSourceTrigger=PropertyChanged}"
                       Visibility="Visible" VerticalAlignment="Top"
                       />
public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(string propertyName)
{
    PropertyChangedEventHandler handler = PropertyChanged;

    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(propertyName));
    }
} 
<DataGrid IsReadOnly="True"  Name="dgClients" AutoGenerateColumns="False" ItemsSource="{Binding Path=Clients, UpdateSourceTrigger=PropertyChanged}">
     <DataGrid.Columns>
                ....
     </DataGrid.Columns>
</DataGrid>