【问题标题】:Store grid rowcount in ViewModel in MVVM在 MVVM 中的 ViewModel 中存储网格行数
【发布时间】:2015-04-12 23:47:00
【问题描述】:

我正在为 WPF 应用程序实现 MVVM。 ViewModel 的创建方式如下:

  • ViewModel:所有 ViewModel 覆盖的基类
  • MainTemplateViewModel:“Masterpage”ViewModel,其中包含 ViewModel 属性 Current,其中包含要显示的 ViewModel
  • CustomerOverviewViewModel:可以放在MainTemplateViewModel.Current中的视图示例

CustomerGridViewModel 包含 Telerik GridView。我想在 MainTemplateViewModel 的标题中显示项目数。 GridView.Items.Count 属性实现了INotifyPropertyChanged,所以我想将此属性绑定到ViewModel.RowCount(因为 CustomerGridViewModel 不知道它是 MainTemplateViewModel 的一部分,因此不能直接绑定到 TextBlock)。我可以反过来使用ViewModel.NumberOfRecords 在标题中显示金额。

如何将 Count 属性绑定到 ViewModel 中的属性?

编辑

我会更详细地描述这个问题:

网格中显示的对象列表是来自 ViewModel 的绑定:

<telerik:RadGridView x:Name="CustomerGrid" ItemsSource="{Binding CustomerViewModels}">    
</telerik:RadGridView>

当过滤内存中的网格时,Telerik 网格会自动更改GridView.Items.Count 属性(这并不意味着更改了原始列表计数!)。因此,如果我可以将此属性绑定到 ViewModel 类中的属性,这将解决问题。

ViewModel.cs

public class ViewModel : INotifyPropertyChanged
{
    private int numberOfRecords;

    public int NumberOfRecords
    {
        get { return numberOfRecords; }
        set { numberOfRecords = value; OnPropertyChanged(); }
    }
}

MainTemplateViewModel.cs

public class MainTemplateViewModel : ViewModel
{
    private ViewModel current = new MainOverviewViewModel();

    public ViewModel Current
    {
        get { return current; }
        set
        {
            if (current != value)
            {
                current = value; OnPropertyChanged();
            }
        }
    }
}

CustomerOverview.xaml.cs

public partial class CustomerOverview : UserControl
{
    public CustomerOverview()
    {
        InitializeComponent();

        this.CustomerGrid.Items.CollectionChanged += ItemsCollectionChanged;
        this.CustomerGrid.Loaded += CustomerGrid_Loaded;
    }

    void CustomerGrid_Loaded(object sender, RoutedEventArgs e)
    {
        /* METHOD 1 PROBLEM: the field to bind to in the MainTemplate is out of scope and accessing a view is not MVVM */
        var binding = new Binding();
        binding.Path = new PropertyPath("Items.Count");
        binding.Source = CustomerGrid;
        ((MainWindow)this.ParentOfType<MainWindow>()).NumberOfRecords.SetBinding(TextBlock.TextProperty, binding);
    }


    void ItemsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        /* METHOD 2 PROBLEM: codebehind code should be in viewmodel */
        ((CustomerOverviewViewModel)this.DataContext).NumberOfRecords = CustomerGrid.Items.Count;
    }
}

【问题讨论】:

    标签: c# wpf mvvm telerik-grid


    【解决方案1】:

    无需在UserControl 中加载数据,只需在其中声明相关类型的DependencyProperty。然后,您可以在主视图模型中加载数据,并从UserControl 简单地将数据绑定到它。您可以执行以下简单示例:

    CustomerOverview.xaml.cs:

    public static DependencyProperty ItemsProperty = DependencyProperty.Register("Items", 
        typeof(ObservableCollection<YourDataType>), typeof(CustomerOverview), 
        new PropertyMetadata(null));
    

    ...

    CustomerOverview.xaml:

    <ListView ItemsSource="{Binding Items, RelativeSource={RelativeSource AncestorType={
        x:Type YourPrefix:CustomerOverview}}}" ... />
    

    ...

    MainWindow.xaml(或任何相关视图):

    <YourPrefix:CustomerOverview 
        Items="{Binding SomeCollectionPropertyInMainTemplateViewModel}" ... />
    

    ...

    MainTemplateViewModel.cs(或任何相关的视图模型)中:

    public ObservableCollection<YourDataType> SomeCollectionPropertyInMainTemplateViewModel
    {
        get { return someCollectionPropertyInMainTemplateViewModel; }
        set
        {
            someCollectionPropertyInMainTemplateViewModel = value; 
            NotifyPropertyChanged("SomeCollectionPropertyInMainTemplateViewModel"); 
            NotifyPropertyChanged("NumberOfRecords"); 
        }
    }
    
    public int NumberOfRecords
    {
        get { return someCollectionPropertyInMainTemplateViewModel.Count; }
    }
    

    【讨论】:

    • 感谢您的回答!我确实看到了两个问题:首先,会有多个网格,所以我希望有逻辑来填充相应视图模型上的网格(而不是全部在父视图中)。第二个问题是网格项在内存中被过滤,唯一正确的计数是 GridView.Items.Count 属性。我在原始帖子的编辑中对此进行了解释。
    • 然后让您的DependencyProperty 公开Count 中的Count 值,并从主视图中将数据绑定到它。
    【解决方案2】:

    Telerik Grid 有两个属性

    可见计数

    TelerikGrid.Items.Count
    

    总数

    TelerikGrid.Items.TotalItemCount
    

    如果这有帮助!

    【讨论】:

      【解决方案3】:

      如果我猜对了,你希望你的主人展示孩子的详细信息。

      您的主人应该能够通过您的当前财产了解您的孩子。 如果您正确使用 MVVM,则绑定到网格的数据来自 child-ViewModel。

      在这种情况下,您的子 ViewModel 中已经有了 itemscount。

      在此之后,您可以在您的 Master 中说类似

       <Label Content="{Binding Current.NumberOfRows}"></Label>
      

      根据this page,您可以将源代码包装在 QueryableCollectionView 中

      【讨论】:

      • 这完全正确,但问题是在 Current.NumberOfRows 属性中获取可见行数。可以通过过滤 Telerik Grid(更改 GridView.Items.Count 属性)在内存中更改可见行数。我已经对原始帖子进行了编辑,详细解释了这一点。
      猜你喜欢
      • 2023-03-16
      • 2020-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-11
      相关资源
      最近更新 更多