WPF工具包数据网格

发布于 2024-07-24 07:06:45 字数 173 浏览 4 评论 0原文

你好,我正在构建一个带有数据网格的 wpf 应用程序, 该模式是模型视图视图模型。

我的所有屏幕都包含一个内容控件,我只是为他分配了视图模型,该模型具有合适的数据模板,

无论如何,我的问题是组合框列,数据上下文是呈现的实体,我需要它作为视图模型。

最好的解决方案是什么?

hello i'm building a wpf app with data grids,
the pattern is model view view model.

all og my screens contains a contentcontrol, and i just assign him the view model, that have a suitable data template,

anyway, my problem is with combo box column, the data context is the presented entity, and i need it to be the view model.

whats the best solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

紙鸢 2024-07-31 07:06:45

我正在使用另一个数据网格,但它可能类似。 我这样做的方式是这样的:

在XAML中,我在资源中定义了一个ObjectDataProvider:

<ObjectDataProvider x:Key="VM" ObjectInstance="{x:Null}" x:Name="vm"/>

然后在分配DataContext(构造函数或DataContextChanged事件)之后,我这样做了:

(this.Resources["VM"] as ObjectDataProvider).ObjectInstance = this.DataContext;

在Combobox xaml中,我将其用作绑定来源:

ItemsSource="{Binding Source={StaticResource VM}, Path=SomeItems, Mode=OneWay}"

不确定它是否适用于微软数据网格,但我想值得一试。

I'm using another datagrid, but it might be similar. The way i did it was like that:

in the XAML, i defined an ObjectDataProvider in the resources:

<ObjectDataProvider x:Key="VM" ObjectInstance="{x:Null}" x:Name="vm"/>

then after assigning the DataContext (either the constructor or the DataContextChanged event), i did this:

(this.Resources["VM"] as ObjectDataProvider).ObjectInstance = this.DataContext;

In the Combobox xaml, i used that as binding source:

ItemsSource="{Binding Source={StaticResource VM}, Path=SomeItems, Mode=OneWay}"

Not sure if it works for the microsoft datagrid, but i guess it's worth a try.

江挽川 2024-07-31 07:06:45

这就是我将 ViewModel 与 ComboBox 结合使用的方式,DataContext 是 ViewModel,而不是底层实体(List)。

ViewModel(Person 是一个带有名称和年龄的简单类):

public class PeopleViewModel : INotifyPropertyChanged
{
    private List<Person> _peopleList;
    private Person _selectedPerson;

    public PeopleViewModel()
    {
        // initialize with sample data
        _peopleList = getPeopleList();
    }

    // gets sample data
    private List<Person> getPeopleList()
    {
        var result = new List<Person>();
        for (int i = 0; i < 10; i++)
        {
            result.Add(new Person("person " + i, i));
        }
        return result;
    }

    public List<Person> PeopleList
    {
        get { return _peopleList; }
    }

    public Person SelectedPerson
    {
        get { return _selectedPerson; }
        set
        {
            if (_selectedPerson == value) return;
            _selectedPerson = value;
            // required so that View know about changes
            OnPropertyChanged("SelectedPerson");
        }
    }
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    // WPF will listen on this event for changes
    public event PropertyChangedEventHandler PropertyChanged;
}

ComboBox 的 XAML:

<ComboBox Name="cmbEnum" Width="150" ItemsSource="{Binding Path=PeopleList}" SelectedValue="{Binding Path=SelectedPerson}" SelectedValuePath="" DisplayMemberPath="Name" ></ComboBox>

在后面的代码中我可以这样做:

    public Window2()
    {
        InitializeComponent();

        vm = new PeopleViewModel();
        // we are listening on changes of ViewModel, not ComboBox
        vm.PropertyChanged += new PropertyChangedEventHandler(vm_PropertyChanged);
        this.DataContext = vm;
    }

    void vm_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
    if (e.PropertyName == "SelectedPerson")
    {
        MessageBox.Show(vm.SelectedPerson.Age.ToString());
    }
    }

    // button1_Click should be probably replaced by Command
    private void button1_Click(object sender, RoutedEventArgs e)
    {
        // sample showing that GUI is updated when ViewModel changes
    vm.SelectedPerson = vm.PeopleList[2];
    }

希望这有帮助,我对 WPF 很陌生,如果这是正确的,我想听到任何反馈使用MVVM的方式,我认为它非常优雅,因为你只在代码中处理ViewModel和Model,并且View可以被替换。

this is how I used ViewModel with ComboBoxes, the DataContext is the ViewModel, not the underlying entity (List<Person>).

ViewModel (Person is a Simple class with Name and Age):

public class PeopleViewModel : INotifyPropertyChanged
{
    private List<Person> _peopleList;
    private Person _selectedPerson;

    public PeopleViewModel()
    {
        // initialize with sample data
        _peopleList = getPeopleList();
    }

    // gets sample data
    private List<Person> getPeopleList()
    {
        var result = new List<Person>();
        for (int i = 0; i < 10; i++)
        {
            result.Add(new Person("person " + i, i));
        }
        return result;
    }

    public List<Person> PeopleList
    {
        get { return _peopleList; }
    }

    public Person SelectedPerson
    {
        get { return _selectedPerson; }
        set
        {
            if (_selectedPerson == value) return;
            _selectedPerson = value;
            // required so that View know about changes
            OnPropertyChanged("SelectedPerson");
        }
    }
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    // WPF will listen on this event for changes
    public event PropertyChangedEventHandler PropertyChanged;
}

XAML for ComboBox:

<ComboBox Name="cmbEnum" Width="150" ItemsSource="{Binding Path=PeopleList}" SelectedValue="{Binding Path=SelectedPerson}" SelectedValuePath="" DisplayMemberPath="Name" ></ComboBox>

And in code behind I can do:

    public Window2()
    {
        InitializeComponent();

        vm = new PeopleViewModel();
        // we are listening on changes of ViewModel, not ComboBox
        vm.PropertyChanged += new PropertyChangedEventHandler(vm_PropertyChanged);
        this.DataContext = vm;
    }

    void vm_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
    if (e.PropertyName == "SelectedPerson")
    {
        MessageBox.Show(vm.SelectedPerson.Age.ToString());
    }
    }

    // button1_Click should be probably replaced by Command
    private void button1_Click(object sender, RoutedEventArgs e)
    {
        // sample showing that GUI is updated when ViewModel changes
    vm.SelectedPerson = vm.PeopleList[2];
    }

Hope this helps, I'm quite new to WPF, I'd like to hear any feedback if this is the right way to use MVVM, I think it's quite elegant since you only deal with the ViewModel and Model in code, and the View can be replaced.

仄言 2024-07-31 07:06:45

我发现实现此目的的最佳方法是为我在网格中使用的所有查找定义一些外部类,并将它们作为静态资源嵌入到模板中

I Found that the best way of implementing this is define some external class for all lookups that i use in grid and embedd them in the template as a static resource

開玄 2024-07-31 07:06:45

我们最终为每个组合框列表提供了具有静态属性的类:(

不能将类本身设置为静态,否则 XAML 将无法打开它,但您也不会得到编译错误)

例如:

public class ZoneList
{
  private static readonly IList<Zone> _Items = new List<Zone>();
  public static IList<Zone> Items
  {
    get { return _Items; }
  }
}

然后在 XAML 中:

<UserControl.Resources>
    <ResourceDictionary>
        <ObjectDataProvider x:Key="myZoneList"   ObjectType="{x:Type StaticLists:ZoneList}"/>
    </ResourceDictionary>
</UserControl.Resources>

<ComboBox ItemsSource="{Binding Path=Items, Source={StaticResource myZoneList}}"></ComboBox>

We ended up having classes with static properties for each of of our combo box lists:

(you can't make the class itself static otherwise XAML won't be able to open it, but you won't get compile errors)

For example:

public class ZoneList
{
  private static readonly IList<Zone> _Items = new List<Zone>();
  public static IList<Zone> Items
  {
    get { return _Items; }
  }
}

and then in XAML:

<UserControl.Resources>
    <ResourceDictionary>
        <ObjectDataProvider x:Key="myZoneList"   ObjectType="{x:Type StaticLists:ZoneList}"/>
    </ResourceDictionary>
</UserControl.Resources>

<ComboBox ItemsSource="{Binding Path=Items, Source={StaticResource myZoneList}}"></ComboBox>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文