Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MVVM、组合框绑定和DatagridTemplateColumn?_C#_Wpf_Mvvm_Combobox_Datagrid - Fatal编程技术网

C# MVVM、组合框绑定和DatagridTemplateColumn?

C# MVVM、组合框绑定和DatagridTemplateColumn?,c#,wpf,mvvm,combobox,datagrid,C#,Wpf,Mvvm,Combobox,Datagrid,我有一个使用组合框的DatagridTemplateColumn,但是ItemSource不会填充绑定的集合 private ObservableCollectionEx<StaffInfoDetail> _sectionStaffMasterDisplay = new ObservableCollectionEx<StaffInfoDetail>(); public ObservableCollectionEx<StaffInfoDetail>

我有一个使用组合框的
DatagridTemplateColumn
,但是
ItemSource
不会填充绑定的集合

 private ObservableCollectionEx<StaffInfoDetail> _sectionStaffMasterDisplay = new ObservableCollectionEx<StaffInfoDetail>();

    public ObservableCollectionEx<StaffInfoDetail> SectionStaffMasterDisplay
    {
        get { return _sectionStaffMasterDisplay; }
        set
        {
            if (value != _sectionStaffMasterDisplay)
            {
                _sectionStaffMasterDisplay = value;
                OnPropertyChanged();
            }
        }
    }
我应该提到的是,
DataGrid
正在正确绑定,并且veiwModel中的任何其他集合都在工作,只是DataGrid中的这个
ComboBox
不起作用

这是MCVE示例代码:

<UserControl 
         d:DataContext="{d:DesignInstance d:Type=viewModels:StaffInfoDetailViewModel, IsDesignTimeCreatable=False}">    

    <DataGrid Grid.Column="0" Grid.ColumnSpan="6" AutoGenerateColumns="False" ItemsSource="{Binding SectionStaffMasterDisplay}" Grid.Row="4" Grid.RowSpan="2" AlternationCount="2" CanUserAddRows="True" CanUserDeleteRows="True" GridLinesVisibility="None" VerticalAlignment="Top" CanUserSortColumns="False">

            <DataGridTemplateColumn Width="190" Header="資格">                    
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox 
                           DisplayMemberPath="ItemName" 
                           SelectedValuePath="ItemName" 
                           SelectedItem="{Binding Path=Name, UpdateSourceTrigger=LostFocus}" 
                           ItemsSource="{Binding Path=LicenceComboBox}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>
           .....more XAML
模型类:

public partial class Licence
{
    public System.Guid Id { get; set; } // ID (Primary key)
    public string ItemName { get; set; } // ItemName (length: 50)
    public string Section { get; set; } // Section (length: 50)

    public Licence()
    {
        InitializePartial();
    }

    partial void InitializePartial();
}
datagrid集合

 private ObservableCollectionEx<StaffInfoDetail> _sectionStaffMasterDisplay = new ObservableCollectionEx<StaffInfoDetail>();

    public ObservableCollectionEx<StaffInfoDetail> SectionStaffMasterDisplay
    {
        get { return _sectionStaffMasterDisplay; }
        set
        {
            if (value != _sectionStaffMasterDisplay)
            {
                _sectionStaffMasterDisplay = value;
                OnPropertyChanged();
            }
        }
    }
对于填充集合的方法,我将调用者添加到来自
public staffinfo detailviewmodel()
的原始代码中:

我看不出
DataContext
有什么问题,但为什么当其他所有属性都正常工作时,这个绑定就不能正确绑定呢


在代码中单步显示要正确填写的
许可证组合框

我在这里看到组合框项源不是DataGrid项源的一部分。因此,它们都共享不同的数据上下文。 Combobox ItemsSource的DataContext是ViewModel,我假设ViewModel是datagrid的DataContext。如果我的假设是正确的,那么您需要将相对源添加到Combobox的ItemsSource绑定中

为此使用以下语法:

<ComboBox 
    DisplayMemberPath="ItemName" 
    SelectedValuePath="ItemName"                            
    ItemsSource="{Binding Path=PathToProperty,
    RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}"
</ComboBox>

我在这里看到Combobox ItemsSource不是DataGrid ItemsSource的一部分。因此,它们都共享不同的数据上下文。 Combobox ItemsSource的DataContext是ViewModel,我假设ViewModel是datagrid的DataContext。如果我的假设是正确的,那么您需要将相对源添加到Combobox的ItemsSource绑定中

为此使用以下语法:

<ComboBox 
    DisplayMemberPath="ItemName" 
    SelectedValuePath="ItemName"                            
    ItemsSource="{Binding Path=PathToProperty,
    RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}"
</ComboBox>

这个问题是关于
数据上下文的。
DataGrid
中的每一行都有自己的
DataContext
——来自
DataGrid.ItemsSource
的集合项

让我们有一个非常简单的例子

using System.Collections.ObjectModel;
using GalaSoft.MvvmLight;

namespace WpfApp4.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        public MainViewModel()
        {
            BarCollection = new ObservableCollection<BarModel>
            {
                new BarModel { Id = 1, Name = "Bar 1", },
                new BarModel { Id = 2, Name = "Bar 2", },
                new BarModel { Id = 3, Name = "Bar 3", },
            };

            FooCollection = new ObservableCollection<FooViewModel>
            {
                new FooViewModel{ Id = 1, },
                new FooViewModel{ Id = 2, },
                new FooViewModel{ Id = 3, },
            };

        }


        public ObservableCollection<BarModel> BarCollection { get; set; }
        public ObservableCollection<FooViewModel> FooCollection { get; set; }
    }

    public class FooViewModel : ViewModelBase
    {
        private BarModel _bar;

        public int Id { get; set; }
        public BarModel Bar { get => _bar; set => Set( ref _bar, value ); }
    }

    public class BarModel
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public override string ToString()
        {
            return Name;
        }
    }
}
通过声明一个
CollectionViewSource
并将
BarCollection
绑定到它,就完成了这个神奇的过程

<Window.Resources>
    <CollectionViewSource 
        x:Key="BarCollectionSource" 
        Source="{Binding Path=BarCollection}"/>
</Window.Resources>

本期是关于
DataContext
的。
DataGrid
中的每一行都有自己的
DataContext
——来自
DataGrid.ItemsSource
的集合项

让我们有一个非常简单的例子

using System.Collections.ObjectModel;
using GalaSoft.MvvmLight;

namespace WpfApp4.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        public MainViewModel()
        {
            BarCollection = new ObservableCollection<BarModel>
            {
                new BarModel { Id = 1, Name = "Bar 1", },
                new BarModel { Id = 2, Name = "Bar 2", },
                new BarModel { Id = 3, Name = "Bar 3", },
            };

            FooCollection = new ObservableCollection<FooViewModel>
            {
                new FooViewModel{ Id = 1, },
                new FooViewModel{ Id = 2, },
                new FooViewModel{ Id = 3, },
            };

        }


        public ObservableCollection<BarModel> BarCollection { get; set; }
        public ObservableCollection<FooViewModel> FooCollection { get; set; }
    }

    public class FooViewModel : ViewModelBase
    {
        private BarModel _bar;

        public int Id { get; set; }
        public BarModel Bar { get => _bar; set => Set( ref _bar, value ); }
    }

    public class BarModel
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public override string ToString()
        {
            return Name;
        }
    }
}
通过声明一个
CollectionViewSource
并将
BarCollection
绑定到它,就完成了这个神奇的过程

<Window.Resources>
    <CollectionViewSource 
        x:Key="BarCollectionSource" 
        Source="{Binding Path=BarCollection}"/>
</Window.Resources>

由于
DataGrid
ComboBox
DataContext
staffinfo-detail
对象,
LicenceComboBox
属性属于
staffinfo-detailviewmodel
类,因此需要使用
RelativeSource
才能绑定到此属性

试试这个:

<DataGridTemplateColumn Width="190" Header="資格">
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <ComboBox 
                DisplayMemberPath="ItemName" 
                SelectedValuePath="ItemName" 
                SelectedValue="{Binding Path=Licence, UpdateSourceTrigger=LostFocus}" 
                ItemsSource="{Binding Path=DataContext.LicenceComboBox, RelativeSource={RelativeSource AncestorType=DataGrid}}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

由于
DataGrid
ComboBox
DataContext
staffinfo-detail
对象,并且
LicenceComboBox
属性属于
staffinfo-detailviewmodel
类,因此需要使用
RelativeSource
才能绑定到此属性

试试这个:

<DataGridTemplateColumn Width="190" Header="資格">
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <ComboBox 
                DisplayMemberPath="ItemName" 
                SelectedValuePath="ItemName" 
                SelectedValue="{Binding Path=Licence, UpdateSourceTrigger=LostFocus}" 
                ItemsSource="{Binding Path=DataContext.LicenceComboBox, RelativeSource={RelativeSource AncestorType=DataGrid}}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>



发布您的
许可证
class@Max实体模型?B/c就是这样。首先编码。您要绑定到的Name属性在哪里?顺便说一句,SelectedItem将绑定所选的许可证实例。@SirRufo,添加了发布您的许可证class@Max实体模型?B/c就是这样。请先编写代码。您要绑定到的Name属性在哪里?顺便说一句,SelectedItem将绑定所选的许可证实例。@SirRufo,AddedIt应该是“UserControl”,因为它是Datagrid的父级,VM附加到“UserControl”,而“UserControl”不做任何操作。还未填充。对于只包含代码片段的问题,没有人能提供准确答案。我们不得不猜太多的东西,我们可能猜错了。如果你想得到一个精确的答案,那就要问一个精确的问题。这个答案是正确的,和你的答案一样清楚question@SirRufo,所以我不能评论这个答案没有帮助?为什么要麻烦?我理解如何帮助人们,就像我通过Excel论坛和VBA在这里帮助许多人一样。我相信答案对你没有帮助,但这不是我的观点。这是正确的,和你的问题一样清楚。我没有说对你有什么帮助,它应该是“UserControl”,因为它是Datagrid的父级,VM附加到“UserControl”上,而“UserControl”不起任何作用。还未填充。对于只包含代码片段的问题,没有人能提供准确答案。我们不得不猜太多的东西,我们可能猜错了。如果你想得到一个精确的答案,那就要问一个精确的问题。这个答案是正确的,和你的答案一样清楚question@SirRufo,所以我不能评论这个答案没有帮助?为什么要麻烦?我理解如何帮助人们,就像我通过Excel论坛和VBA在这里帮助许多人一样。我相信答案对你没有帮助,但这不是我的观点。这是正确的,和你的问题一样清楚。我没说对你有什么帮助