【问题标题】:MVVM Datagrid to Observable Collection binding of generic typesMVVM Datagrid 到泛型类型的 Observable Collection 绑定
【发布时间】:2015-10-14 17:10:42
【问题描述】:

我有一个 xaml UserControl,其中 DataContext 引用“控件”-ViewModel。

mc:Ignorable="d" d:DataContext="{d:DesignInstance controls:ControlViewModel}"

此外,我已经将 ItemsSource 绑定到一个 ObservableCollection,它是来自“Data”-ViewModel 的泛型。 (请注意:这些数据仅用于演示)

    <DataGrid ItemsSource="{Binding DataCollection}" SelectedItem="{Binding SelectedData}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
            <DataGridTextColumn Header="Age" Visibility="{Binding AgeVisibility}"  Binding="{Binding Age}"/>
        </DataGrid.Columns>
    </DataGrid>

public class ControlViewModel
{
        private ObservableCollection<DataViewModel> _dataViewModels;
        public ObservableCollection<DataViewModel> DataViewModels
        {
            get { return _dataViewModels; }
            set
            {
                   _dataViewModels = value;
                    RaisePropertyChanged("DataViewModels");
            }
        }
}

“数据”-ViewModel 具有以下属性,我已将其绑定到特定的 DataGridTextColumn(如您所见)。

public class DataViewModel
{
        private string _name;
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                RaisePropertyChanged("Name");
            }
        }

        private int _age;
        public int Age
        {
            get { return _age; }
            set
            {
                _age = value;
                RaisePropertyChanged("Age");
            }
        }

        private Visibility _ageVisibility;
        public Visibility AgeVisibility
        {
            get { return _ageVisibility; }
        }
}

一切正常,希望“年龄”列的 Visibilty 属性不会轻易引用可观察集合的通用 DataViewModel(属性),例如绑定属性。所以它无法解决,它总是默认的。

【问题讨论】:

  • 您的问题是什么?仅仅是 Resharper 是合规的还是某些东西不起作用?如果您遇到问题,我建议您取消“AgeVisibility”属性并改用值转换器。如果您想保留该属性但不想要 setter,则将 RaisePropertyChanged("AgeVisibility") 添加到您的 Age setter 并将可见性逻辑计算放在那里。
  • @MatthewWhited 问题是,如何将 Visibility 属性绑定到 DataViewModel 的 AgeVisibility 属性?我的方法不起作用,因为它没有绑定到可观察集合的泛型类型,因此无法找到。我在ctor中设置了私有字段_ageVisibilty,所以我不需要setter,即使我使用它,它也不起作用。
  • AgeVisibility 何时更改或设置?为什么你不把它设置为像 Age 或 Name 这样的属性,那样当你设置它时一切都会起作用?
  • 不,绑定不正确。它与缺少的 RaisePropertyChanged 设置器无关。没有找到,因为我觉得像Binding="{Binding Name}"这样的DataGridTextColumn属性“Binding”只引用了ObservableCollection的一个对象,所以这是通过泛型=> ObservableCollection DataViewModels找到的。但是 Property Visibility 没有引用它,所以没有找到它,ReSharper 也为此发出警告:“无法解析属性”...

标签: c# wpf xaml mvvm data-binding


【解决方案1】:

如果您想要一个可绑定的属性,则将第二个RaisePropertyChanged 添加到控制只读属性的属性中。

public class DataViewModel
{
    //other stuff

    private int _age;
    public int Age
    {
        get { return _age; }
        set
        {
            _age = value;
            RaisePropertyChanged("Age");
            RaisePropertyChanged("AgeVisibility");
        }
    }

    public Visibility AgeVisibility
    {
        get { return this.Age > 0 ? Visibility.Visible : Visibility.Hidden; }
    }
}

您还可以使用类型转换器,例如 this

【讨论】:

  • 该属性也是“可绑定”的,只有一个 getter,因为我只在构造函数中“设置”(私有字段)一次。问题是,它无法解决,请参阅上面的答案。
  • 它应该可以正常工作。你在哪里设置_ageVisibility 的值。那时调用RaisePropertyChanged(...) 方法。 Resharper 抱怨并不意味着 XAML 不能正常工作。就像你破碎的实现不会让我的回答错。
  • 顺便说一句,你的基类在哪里,或者至少是INotifyPropertyChanged
  • 这不是问题。我在这里找到了解决方案stackoverflow.com/a/22074985/4367848
  • 好吧...这是一个不同的问题,然后“ReSharper 还警告说 AgeVisiblity 无法解决”
猜你喜欢
  • 2016-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多