Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.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# Wpf-绑定一个gridcontrol选定的行数据并将其填充到另一个gridcontrol中_C#_Wpf - Fatal编程技术网

C# Wpf-绑定一个gridcontrol选定的行数据并将其填充到另一个gridcontrol中

C# Wpf-绑定一个gridcontrol选定的行数据并将其填充到另一个gridcontrol中,c#,wpf,C#,Wpf,我有一个gridcontrol,其中包含我在代码中没有提到的各种字段 <dxg:GridControl HorizontalAlignment="Stretch" Height="300" VerticalAlignment="Top" x:Name="grid1" AutoPopulateColumns="False" ItemsSource="{Binding Collection1}" > <dxg:GridContr

我有一个gridcontrol,其中包含我在代码中没有提到的各种字段

<dxg:GridControl   HorizontalAlignment="Stretch" Height="300"  VerticalAlignment="Top" x:Name="grid1"  AutoPopulateColumns="False" ItemsSource="{Binding Collection1}"    >
                    <dxg:GridControl.View >
                        <dxg:TableView x:Name="TableView1" />
                    </dxg:GridControl.View>
                .   
                .   
                .   
                .

.   
.   
.   
.

我在同一页上有另一个网格控件,其中包含多个字段

<dxg:GridControl HorizontalAlignment="Stretch" Height="250"  VerticalAlignment="Top" x:Name="grid2"  AutoPopulateColumns="False"
                                 ItemsSource="{Binding ElementName="TableView1" ,path=Collection2.FocusedRow}"    >
                    <dxg:GridControl.View >
                        <dxg:TableView x:Name="TableView2"  />
                    </dxg:GridControl.View>
                .   
                .   
                .   
                .

.   
.   
.   
.

现在collection1Id是主键,collection2colID是外键,两者都有关系

这里的场景是,如果我在网格1中选择一行,那么所有相应的记录都必须显示在网格2中

 public class myCollection: BindingList<orders>
{
     public DataContext dc;

    public myCollection(IList<orders> list)
        : base(list)
    {
    }

    protected override void RemoveItem(int index)
    {
        orders deleteItem = this.Items[index];

        if (Dc.Order != null)
        {
            Dc.Order.DeleteOnSubmit(deleteItem);
        }
        base.RemoveItem(index);
    }

}
公共类myCollection:BindingList
{
公共数据上下文dc;
公共myCollection(IList列表)
:基本(列表)
{
}
受保护的覆盖void removietem(int索引)
{
orders deleteItem=此.Items[索引];
如果(Dc.Order!=null)
{
Dc.Order.DeleteOnSubmit(删除项);
}
基本删除项(索引);
}
}
我的订单通用类和master通用类是相同的


如果我说的是XAML属性,那么在这里,您希望在第一个Datagrid的SelectedItem属性的基础上更新第二个Datagrid的ItemsSource属性

要实现这一点,请在ViewModel中添加一个新属性“SelectedItemDg1”,该属性将保存第一个DataGrid的选择。在“SelectedItemDg1”属性的Setter中,根据需要设置Collection2

确保实现INotifyPropertyChanged接口,并为这两个集合使用ObservableCollection类型

以下是相同类型的代码示例:

模型类:

公共类国家
{
公共字符串CountryName{get;set;}
public int CountryId{get;set;}
公共列表状态{get;set;}
}
公共阶级国家
{
公共字符串StateName{get;set;}
public int StateId{get;set;}
}
视图模型:

public类MainWindowViewModel:INotifyPropertyChanged
{
公共主窗口视图模型()
{
CountriesCollection=新的ObservableCollection();
StateCollection=新的ObservableCollection();
LoadData();
}
私人可观测采集(国家采集);;
公共观察收集国家/地区收集
{
获取{return\u countries集合;}
设置
{
_CountriesCollection=值;
NotifyPropertyChanged(“CountriesCollection”);
}
}
私有可观测集合(StatesCollection);;
公共可观测集合状态集合
{
获取{return\u StatesCollection;}
设置
{
_StatesCollection=值;
NotifyPropertyChanged(“StateCollection”);
}
}
私人国家(u选择的国家);;
公共国家/地区选择国家/地区
{
获取{return\u SelectedCountry;}
设置
{
_SelectedCountry=值;
如果(_SelectedCountry!=null&&u SelectedCountry.States!=null)
{
StateCollection=新的ObservableCollection(_SelectedCountry.States);
}
NotifyPropertyChanged(“SelectedCountry”);
}
}
私有void LoadData()
{
if(countriescolection!=null)
{
Countries集合。添加(新国家/地区)
{
CountryId=1,
CountryName=“印度”,
国家=新名单
{
新州{StateId=1,StateName=“古吉拉特邦”},
新州{StateId=2,StateName=“旁遮普”},
新州{StateId=3,StateName=“Maharastra”}
}
});
Countries集合。添加(新国家/地区)
{
CountryId=2,
CountryName=“Chine”,
国家=新名单
{
新状态{StateId=4,StateName=“Chine_State1”},
新状态{StateId=5,StateName=“Chine_State2”},
新状态{StateId=6,StateName=“Chine_State3”}
}
});
Countries集合。添加(新国家/地区)
{
CountryId=3,
CountryName=“日本”,
国家=新名单
{
新州{StateId=7,StateName=“Japan_State1”},
新国家{StateId=8,StateName=“Japan_State2”},
新国家{StateId=9,StateName=“Japan_State3”}
}
});
}
}
公共事件属性更改事件处理程序属性更改;
私有void NotifyPropertyChanged(字符串信息)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(信息));
}
}
哈姆:


这里我有DataGrid的AutoGenerateColumns属性,但您必须根据需要进行更改


我希望这个示例代码能让您更容易理解。

我发现,在集合上进行这种主详细信息绑定的最简单、最干净的方法是将
ObservableCollection
包装在一个类中,公开它的
ListCollectionView
并将您的
ItemsSource
绑定到它,如下所示(它有一些用于简化xml序列化的额外代码):

然后,保持网格同步就这么简单:

<DataGrid ItemsSource="{Binding Collection1.View, Mode=OneWay}" 
          IsSynchronizedWithCurrentItem="True" />
<DataGrid ItemsSource="{Binding Collection1.CurrentItem.Collection2.View, Mode=OneWay}"
          IsSynchronizedWithCurrentItem="True" />
此外,您还可以管理代码隐藏中的选择,例如:

Collection1.CurrentItem=null;
将清除collec上的选择
 <StackPanel Orientation="Horizontal" >
    <DataGrid AutoGenerateColumns="True" 
              Height="300" Width="300" 
              HorizontalAlignment="Left" Margin="30" 
              ItemsSource="{Binding CountriesCollection}" 
              SelectedItem="{Binding SelectedCountry}">

    </DataGrid>
    <DataGrid AutoGenerateColumns="True" 
              Height="300" Width="300" 
              HorizontalAlignment="Left" Margin="30"  
              ItemsSource="{Binding SelectedCountry.States}">

    </DataGrid>
</StackPanel>
public class ViewableCollection<T> : ObservableCollection<T>
{
    private ListCollectionView _View;

    public ViewableCollection(IEnumerable<T> items)
        : base(items) { }

    public ViewableCollection()
        : base() { }

    [XmlIgnore]
    public ListCollectionView View
    {
        get
        {
            if (_View == null)
            {
                _View = new ListCollectionView(this);
                _View.CurrentChanged += new EventHandler(InnerView_CurrentChanged);
            }
            return _View;
        }
    }

    [XmlIgnore]
    public T CurrentItem
    {
        get
        {
            return (T)this.View.CurrentItem;
        }
        set
        {
            this.View.MoveCurrentTo(value);
        }
    }

    private void InnerView_CurrentChanged(object sender, EventArgs e)
    {
        this.OnPropertyChanged(new PropertyChangedEventArgs("CurrentItem"));
    }

    public void AddRange(IEnumerable<T> range)
    {
        if (range == null)
            throw new ArgumentNullException("range");

        foreach (T item in range)
        {
            this.Items.Add(item);
        }

        this.OnPropertyChanged(new PropertyChangedEventArgs("Count"));
        this.OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
        this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, (IList)range.ToList()));
    }

    public void ReplaceItems(IEnumerable<T> range)
    {
        if (range == null)
            throw new ArgumentNullException("range");

        this.Items.Clear();
        foreach (T item in range)
        {
            this.Items.Add(item);
        }

        this.OnPropertyChanged(new PropertyChangedEventArgs("Count"));
        this.OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
        this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }

    public void RemoveItems(IEnumerable<T> range)
    {

        if (range == null)
            throw new ArgumentNullException("range");

        foreach (T item in range)
        {
            this.Items.Remove(item);
        }

        this.OnPropertyChanged(new PropertyChangedEventArgs("Count"));
        this.OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
        this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, (IList)range.ToList()));
    }

    public void ClearAll()
    {
        IList old = this.Items.ToList();
        base.Items.Clear();
        this.OnPropertyChanged(new PropertyChangedEventArgs("Count"));
        this.OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
        this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, old));
    }

    public void CallCollectionChaged()
    {
        this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }

    // necessary for xml easy serialization using [XmlArray] attribute
    public static implicit operator List<T>(ViewableCollection<T> o)
    {
        return o == null ? default(List<T>) : o.ToList();
    }

    // necessary for xml easy serialization using [XmlArray] attribute
    public static implicit operator ViewableCollection<T>(List<T> o)
    {
        return o == default(List<T>) || o == null ? new ViewableCollection<T>() : new ViewableCollection<T>(o);
    }
}
[ImplementPropertyChanged]
public class MyViewModel
{
    public ViewableCollection<MySecondViewModel> Collection1 { get; set; }

    public MyViewModel()
    {
        this.Collection1 = new ViewableCollection<MySecondViewModel>();
    }
}

[ImplementPropertyChanged]
public class MySecondViewModel
{ 
    public string MyColumn1 { get; set; }
    public string MyColumn2 { get; set; }
    public ViewableCollection<MyThirdViewModel> Collection2 { get; set; }

    public MySecondViewModel()
    {
        this.Collection1 = new ViewableCollection<MyThirdViewModel>();
    }
}

[ImplementPropertyChanged]
public class MyThirdViewModel
{ 
    public string MyColumn1 { get; set; }
    public string MyColumn2 { get; set; }
}

//...
this.DataContext = new MyViewModel();
<DataGrid ItemsSource="{Binding Collection1.View, Mode=OneWay}" 
          IsSynchronizedWithCurrentItem="True" />
<DataGrid ItemsSource="{Binding Collection1.CurrentItem.Collection2.View, Mode=OneWay}"
          IsSynchronizedWithCurrentItem="True" />
<TextBlock Text="{Binding Collection1.CurrentItem.Collection2.CurrentItem.Column1}" />
Collection1.CurrentItem=null;
Collection1.View.SortDescriptions.Add(new SortDescription("Column1",ListSortDirection.Ascending));