powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Master-detail combobox внутри datagrid
2 сообщений из 2, страница 1 из 1
Master-detail combobox внутри datagrid
    #39400780
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет, вновь возникающие траблы по Datagrid.
авторDataGrid вообще глючное ####, вы еще с ним горя хапните, я вам обещаю :) Совершенно верно.
Проблема:
есть Datagrid, в каждой нем 2 combobox- наименование организации и реквизиты договоров - соответственно в отношении Master-detail.
К каждой организации привязаны свои договоры. Нужно, чтобы при выборе организации, во втором combobox отражались договоры только для данной организации.
Рабочий пример :
Код: xml
1.
2.
3.
4.
5.
6.
7.
<ComboBox x:Name="company_cbx1"
                            ItemsSource="{Binding cmp_list}"
                            DisplayMemberPath="company_Name"/>


 <ComboBox   ItemsSource="{Binding Path=SelectedItem.list_of_contracts,ElementName=company_cbx1}"
                   DisplayMemberPath="n_contract"/>


вне DataGrid- работает. Вставляю combobox внутрь datagrid

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
     <DataGridTemplateColumn Header="Наименование организации">
                    <DataGridTemplateColumn.CellTemplate >
                        <DataTemplate >
                            <TextBlock Text="{Binding name_org_util.company_Name}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>


                    <DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate >
                            <ComboBox x:Name="company_cbx"
                            ItemsSource="{Binding Path=DataContext.cmp_list,
                            RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
                            DisplayMemberPath="company_Name"
                            SelectedValuePath="id"
                            SelectedItem="{Binding name_org_util,
                            UpdateSourceTrigger=PropertyChanged}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>


                <DataGridTemplateColumn Header="Реквизиты договора" >
                    <DataGridTemplateColumn.CellTemplate >
                        <DataTemplate >
                            <TextBlock Text="1"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>


                    <DataGridTemplateColumn.CellEditingTemplate >
                        <DataTemplate >
                            <ComboBox   ItemsSource="{Binding Path=SelectedItem.list_of_contracts,ElementName=company_cbx}"
                                        DisplayMemberPath="n_contract"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>



и detail-combobox пустой. В списке ошибок пишет
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=company_cbx'. BindingExpression:Path=SelectedItem.list_of_contracts; DataItem=null; target element is 'ComboBox' (Name=''); target property is 'ItemsSource' (type 'IEnumerable') . Типа не находит элемент с таким именем. Пробовал найти вариант биндинга без ElementName, но использование именно внутри DataGridа не нашел. Также нашел жесткий вариант с полным сканированием визуального дерева и прочей черной магией, а также сохранять значение из master-combobox во viemodel и потом фильтровать detail-сombobox. Есть ли возможность обойтись одним лишь xaml для фикса?

Структура классов:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public class Company
{

	private UInt32 _id;
	public UInt32 id {
		get { return _id; }
		set { _id = value; }
	}

	private string _company_Name;
	public string company_Name {
		get { return _company_Name; }
		set { _company_Name = value; }
	}

	private List<Contract> _list_of_contracts;
	public List<Contract> list_of_contracts {
		get { return _list_of_contracts; }
		set { _list_of_contracts = value; }
	}

}


using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public class Contract
{
	private UInt32 _id;
	public UInt32 id {
		get { return _id; }
		set { _id = value; }
	}


	private UInt32 _n_contract;
	public UInt32 n_contract {
		get { return _n_contract; }
		set { _n_contract = value; }
	}


	private System.DateTime _date_contract;
	public System.DateTime date_contract {
		get { return _date_contract; }
		set { _date_contract = value; }
	}


}
...
Рейтинг: 0 / 0
Master-detail combobox внутри datagrid
    #39401135
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пример:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
<Application x:Class="DataGrid_ComboBox_MasterDetail.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:DataGrid_ComboBox_MasterDetail"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <local:MainModel x:Key="{x:Type local:MainModel}"/>
    </Application.Resources>
</Application>


Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
<Window x:Class="DataGrid_ComboBox_MasterDetail.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DataGrid_ComboBox_MasterDetail"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{StaticResource {x:Type local:MainModel}}">
    <Window.Resources>
        
        <Style TargetType="{x:Type DataGrid}">
            <Setter Property="AutoGenerateColumns" Value="False"/>
            <Setter Property="Margin" Value="5"/>
            <Setter Property="MinRowHeight" Value="30"/>
        </Style>
        
        <DataTemplate x:Key="{x:Type local:Contract}" DataType="{x:Type local:Contract}">
            <TextBlock Text="{Binding Name}"/>
        </DataTemplate>

        <DataTemplate x:Key="{x:Type local:Person}" DataType="{x:Type local:Person}">
            <TextBlock Text="{Binding Name}"/>
        </DataTemplate>

    </Window.Resources>
        
    <Grid>
        <DataGrid ItemsSource="{Binding Rows}">
            <DataGrid.Columns>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Person.Name}" VerticalAlignment="Center" Margin="2"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                    <DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{Binding Persones, Source={StaticResource {x:Type local:MainModel}}}" 
                                        SelectedItem="{Binding Person, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                        ItemTemplate="{StaticResource {x:Type local:Person}}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>
                
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Contract.Name}" VerticalAlignment="Center" Margin="2"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                    <DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate DataType="{x:Type local:Row}">
                            <ComboBox ItemsSource="{Binding Contracts}" 
                                        SelectedItem="{Binding Contract, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                        ItemTemplate="{StaticResource {x:Type local:Contract}}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>



Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Data;

namespace DataGrid_ComboBox_MasterDetail
{
    public abstract class BaseModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class Row : BaseModel
    {
        private Person _person;

        public Person Person
        {
            get { return _person; }
            set
            {
                if (!Equals(_person, value))
                {
                    _person = value;
                    Contract = null;
                    OnPropertyChanged(nameof(Person));
                    OnPropertyChanged(nameof(Contract));
                    OnPropertyChanged(nameof(Contracts));
                }
            }
        }

        public Contract Contract { set; get; }

        public IList<Contract> Contracts => Person?.Contracts;

    }

    public class Person
    {
        public Person(string name, int age) { Name = name; Age = age; }
        public int Age { get; }
        public string Name { get; }
        public IList<Contract> Contracts { set; get; }
    }

    public class Contract
    {
        public Contract(string name) { Name = name; }
        public string Name { get; }
    }

    public class MainModel
    {
        public MainModel()
        {
            Persones = new List<Person>(3)
            {
                new Person ("vb_sub", 25)
                {
                    Contracts = new []
                    {
                        new Contract("Contract1"),
                        new Contract("Contract2"),
                        new Contract("Contract3")
                    }
                },
                new Person ("Roman Mejtes", 33)
                {
                    Contracts = new []
                    {
                        new Contract("Contract4"),
                        new Contract("Contract5"),
                        new Contract("Contract6"),
                        new Contract("Contract7")
                    }
                },
                new Person ("Ivan Ivanov", 54)
                {
                    Contracts = new []
                    {
                        new Contract("Contract8"),
                        new Contract("Contract9"),
                        new Contract("Contract10"),
                        new Contract("Contract11"),
                        new Contract("Contract12")
                    }
                }
            };

            Rows = new List<Row>
            {
                new Row
                {
                    Person = Persones[0],
                    Contract = Persones[0].Contracts[0]
                },
                new Row
                {
                    Person = Persones[1],
                    Contract = Persones[1].Contracts[0]
                },
            };

            ListCollectionView view = (ListCollectionView)CollectionViewSource.GetDefaultView(Rows);

        }
        public IList<Row> Rows { set; get; }
        public IList<Person> Persones { get; }
    }
}
...
Рейтинг: 0 / 0
2 сообщений из 2, страница 1 из 1
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Master-detail combobox внутри datagrid
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]