C# WPF Как правильно привязать Combo box к сущности?

535
09 декабря 2016, 08:45

В комментариях привёл ссылку,где отвечают на мой вопрос,но я не понимаю как он привязывает выбранную сущность в combobox к нужной сущности(Stelug к plavka),а там спросить не могу - репы не хватает.

Программа на C# WPF паттерн MVVM. Есть сущность detail и employee(LinqTOSQL) и они связаны. Хочу в datagrid выводить detail и в отдельной колонке работников в виде combobox(DataGridComboBoxColumn),чтобы их можно было менять для этой сущности. Нашел вроде, сделал подобно http://www.sql.ru/forum/1169706/ne-bindyatsya-dannye-k-combobox-v-wpf-datagrid

ComboBox появился и данные тоже, но при изменении элемента он становится красным(исключение судя по-всему) и не привязывается к сущности(потому что я не привязал, а как не понимаю). Наверняка нужно это прописать в одном из свойств. Но в каком?

Привожу код той самой колонки

<DataGridComboBoxColumn 
                                DisplayMemberPath="FullName"
                                SelectedValuePath="idemployee"
                                SelectedValueBinding="{Binding employee}" 
                        Header="ФИО отв.лица">
                        <DataGridComboBoxColumn.ElementStyle>
                            <Style TargetType="ComboBox">
                                <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.GetEmployee}"/>
                                <Setter Property="IsReadOnly" Value="True"/>
                            </Style>
                        </DataGridComboBoxColumn.ElementStyle>
                        <DataGridComboBoxColumn.EditingElementStyle>
                            <Style TargetType="ComboBox">
                                <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.GetEmployee}"/>
                            </Style>
                        </DataGridComboBoxColumn.EditingElementStyle>
                    </DataGridComboBoxColumn>

Привожу код VM

public class DetailVM:ViewModelBase
{
    private TechDepDBDataContext _techDepDB;
    public DetailVM(TechDepDBDataContext db)
    {
        this._techDepDB = db;
        _details = new ObservableCollection<detail>() { new detail { NameDetail = "ara", CountDetail = 2 } };
    }
    public string EssenceName { get { return "Деталь"; } }
    //public DTG_Detail UEdtg
    //{
    //get {return _uedtg;}
    //    set { _uedtg = value; }
    //}
    #region Read/Update
    private List<officememo> _officememo;
    public List<officememo> Select
    {
        get
        {
            _officememo = (from c in _techDepDB.officememo
                          select c).ToList();
            return _officememo;
        }
    }
    #endregion
    public List<employee> GetEmployee
    {
        get 
        {
            var emp= (from c in _techDepDB.employee
                          select c).ToList();
        return emp;
        }
    }
    #region Create
    private ObservableCollection<detail> _details;
    public ObservableCollection<detail> InsertDetailCol
    {
        get
        {
            OnPropertyChanged("_details");
            return _details;
        }
    }

    public void Insert()
    {
        _techDepDB.detail.InsertAllOnSubmit(_details);
        _details.Clear();
        _techDepDB.SubmitChanges();

    }
    #endregion
}

Код главной VM public class MainVM:ViewModelBase { private TechDepDBDataContext _db; ObservableCollection _pages;

    public ObservableCollection<ViewModelBase> Pages
    {
        get { return _pages; }
        set { _pages = value; }
    }
    public MainVM()
    {_db=new TechDepDBDataContext();
    _db.LoadOptions = GetLoadOption();
        _pages = new ObservableCollection<ViewModelBase>();
        _pages.Add(new DetailVM(_db));
        _pages.Add(new OperationVM(_db));
        _pages.Add(new OfficeMemoVM(_db));
        _pages.Add(new DeviceVM(_db));
        _pages.Add(new ProjectVM(_db));
    }

XAML разметка MainView

<Window x:Class="TechDepCRM.MainView"
    x:Name="MainV"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainView" Height="535" Width="778"
    xmlns:viewModel="clr-namespace:TechDepCRM.ViewModels"
    xmlns:view="clr-namespace:TechDepCRM.Views"
    DataContext="{Binding MainVM,ElementName=MainV}">
<Window.Resources>
    <DataTemplate DataType="{x:Type viewModel:DetailVM}">
    <view:DetailView />
    </DataTemplate>
    <DataTemplate DataType="{x:Type viewModel:OperationVM}">
        <view:OperationView />
    </DataTemplate>
    <DataTemplate DataType="{x:Type viewModel:OfficeMemoVM}">
        <view:OfficeMemoView />
    </DataTemplate>
    <DataTemplate DataType="{x:Type viewModel:DeviceVM}">
        <view:DeviceView />
    </DataTemplate>
    <DataTemplate DataType="{x:Type viewModel:ProjectVM}">
                  <view:ProjectView />
    </DataTemplate>
</Window.Resources>
<TabControl Name="Tabs" ItemsSource="{Binding Pages}" Margin="10,36,0,0">
    <TabControl.ItemContainerStyle>
        <Style TargetType="TabItem">
            <Setter Property="Header" Value="{Binding EssenceName}" />
        </Style>
    </TabControl.ItemContainerStyle>
</TabControl>

UPDATE 16.09.16

Тег DataGrid

<DataGrid  ItemsSource="{Binding ElementName=CBOfficeMemo, Path=SelectedItem.detail}"

ComboBox к которому привязывается DataGrid(под "Фильтр" на форме)

<ComboBox Name="CBOfficeMemo" ItemsSource="{Binding Select}" HorizontalAlignment="Left" Margin="58,119,0,0" VerticalAlignment="Top" Width="120" Height="19">
    <ComboBox.ItemTemplate>
        <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding NumOfficeMemo}"></TextBlock>
                    <TextBlock Text="\"></TextBlock>
                    <TextBlock Text="{Binding YearOfficeMemo}"></TextBlock>
                </StackPanel>
            </DataTemplate>
    </ComboBox.ItemTemplate>
    </ComboBox>
Answer 1

Нашел решение проблемы (предыстория в чатике). Спасибо VladD.

Поклацав интерфейс, я внимательно изучил Output и наткнулся на странную строчку:

"System.Windows.Data Error: 23 : Cannot convert '10' from type 'Int32' to type 'TechDepCRM.employee' for 'en-US' culture with default conversions; consider using Converter property of Binding. NotSupportedException:'System.NotSupportedException: TypeConverter не может выполнить преобразование из System.Int32."

Появилось это при выборе employee и выхода со строчки/клетки

Возник вопрос "Где происходит преобразование?".

Узнал в цифре 10 идентификатор работника моего.

"Где я вообще работаю с идентификатором?"

Вот в этой строчке SelectedValuePath="idemployee" Из прочитанного мною ранее(блин) можно сказать, что через это свойство мы видим обращение к элементу ComboBox(не совсем понял, но советовали использовать это для работы с элементами через id) В итоге сначала пытаясь изменить значение на Entity,employee. Полностью ее убрал и все заработало. В бд все записывается.

Ответ

Уберите строчку SelectedValuePath или используйте ее грамотно

READ ALSO
Выделение строк datagridview C#

Выделение строк datagridview C#

Нужно, что бы при нажатом Ctrl строки выделялись, и не снималось выделение при повторном клике на одну из выделенных строкТо есть - зажали Ctrl - > кликнули...

394
Помогите пожалуйста разобраться в коде

Помогите пожалуйста разобраться в коде

Может ли кто-то объяснить значение третьей строки в коде?

223
Изменить курсор на свой C# WinForms

Изменить курсор на свой C# WinForms

Подскажите как изменить курсор на свой? Делаю так :

374
Entity Framework прямой запрос без контекста базы

Entity Framework прямой запрос без контекста базы

Возможно ли сделать запрос используя средства EF не описывая при этом контекст базы данных, либо создав и описав его непосредственно в функции...

268