Модераторы: gambit, Kefir, Partizan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Combobox Binding 
V
    Опции темы
Ronin08
Дата 17.6.2011, 23:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 16.2.2008
Где: г.Москва

Репутация: нет
Всего: 1



Доброго времени суток. 
Допустим В БД имеется 2 табл. 1-Vendor(VendorId, Name) 2-Application(AppId, Name, VendorId(ссылка на Vendor.VendorId))
Я использую Entity Framework

В приложении WPF имеется textbox забинденый на Application.Name и combobox забинденный на Vendor.Name
нужно чтобы в combobox выделялась запись соответствующая Application.VendorId

Код

    <Window.Resources>
        <CollectionViewSource x:Key="applicationViewSource" d:DesignSource="{d:DesignInstance my:Application, CreateList=True}" />
        <CollectionViewSource x:Key="vendorViewSource" d:DesignSource="{d:DesignInstance my:Vendor, CreateList=True}" />
    </Window.Resources>

    <Grid>
        <StackPanel Orientation="Horizontal" VerticalAlignment="Top" DataContext="{StaticResource applicationViewSource}">
            <Label Content="Application Name :"/>
            <TextBox Height="23"  Name="nameTextBox" Text="{Binding Path=Name, Mode=TwoWay}" Width="120" />
        </StackPanel>
        
        <StackPanel Margin="0,30" Orientation="Horizontal" VerticalAlignment="Top"
                      DataContext="{StaticResource vendorViewSource}">
            <Label Content="Vendor Name:" Grid.Column="0" Grid.Row="0"/>
            <ComboBox Name="cbxVendorName" VerticalAlignment="Center" Width="120"
                      ItemsSource="{Binding}"
                      DisplayMemberPath="Name"/>
        </StackPanel>
    </Grid>
 

Код

       private void Window_Loaded(object sender, RoutedEventArgs e)
      {
            using (var context = new Model.D001Entities())
            {
                var query = from c in context.Applications 
                            where c.IdApp == 4 
                            select c;
                var applicationViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("applicationViewSource")));
                applicationViewSource.Source = query;
            }
           
            using (var context = new Model.D001Entities())
            {
                var query = from c in context.Vendors 
                            select c;
                var vendorViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("vendorViewSource")));
                vendorViewSource.Source = query;
            }
        }





Это сообщение отредактировал(а) Ronin08 - 18.6.2011, 00:00
--------------------
Зачем вставать рано или поздно? Надо вставать вовремя
PM MAIL   Вверх
Kefir
Дата 18.6.2011, 00:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


«Hakuna Matata»
***


Профиль
Группа: Комодератор
Сообщений: 1878
Регистрация: 25.1.2003
Где: Tampere, Suomi

Репутация: 22
Всего: 87



PM MAIL WWW Skype   Вверх
Ronin08
Дата 18.6.2011, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 16.2.2008
Где: г.Москва

Репутация: нет
Всего: 1



Kefir, я понимаю, что SelectedValue, просто во всех примерах что я видел работают с одной коллекций, например в той ссылке что ты дал есть только коллекция Employee.
В моем случае есть две коллекции Applications  и Vendors. Надо для текущего  Applications.VendorId выбрать (SelectedValue) запись из   Vendors.VendorId

--------------------
Зачем вставать рано или поздно? Надо вставать вовремя
PM MAIL   Вверх
Kefir
Дата 18.6.2011, 23:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


«Hakuna Matata»
***


Профиль
Группа: Комодератор
Сообщений: 1878
Регистрация: 25.1.2003
Где: Tampere, Suomi

Репутация: 22
Всего: 87



Я не сильно разбирался в твоих биндингах и подобном, но забинди примерно так:
Код

<ComboBox SelectedValue="{Binding DataContext.VendorId, ElementName=nameTextBox}" .../>

PM MAIL WWW Skype   Вверх
Ronin08
Дата 19.6.2011, 00:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 16.2.2008
Где: г.Москва

Репутация: нет
Всего: 1



Kefir, спасибо за ответ, но не так .
Цитата

ElementName=nameTextBox

это не верно. nameTextBox здесь не причем.

к nameTextBox  биндится Application.Name, а связывать надо по Application.VendorId


например, должно быть так:
в nameTextBox.Text у меня  "Photoshop"  а в cbxVendorName есть такие записи: Microsoft; Mozilla; Adobe; Kaspersky Lab; 
значит cbxVendorName.SelectedValue должно быть "Adobe".

--------------------
Зачем вставать рано или поздно? Надо вставать вовремя
PM MAIL   Вверх
Rohoss
Дата 19.6.2011, 01:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Ronin08, задачи такого типа хорошо решаются у ViewModel паттерна MVVM


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
Rohoss
  Дата 19.6.2011, 02:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Прикрепил решение. Однако тут я сделал на примере обычных коллекций, но думаю с EF будет тоже самое. Для использования шаблона MVVM я не использовал никаких тулкитов а просто создал класс MainWindowViewModel и реализовал в нём интерфейс INotifyPropertyChanged. В результате, что мы имеем:
Три класса данных
TableApplication
Код

        public int AppId { get; set; }

        public string Name { get; set; }

        public int VendorId { get; set; }

TableVendor
Код

    public class TableVendor
    {
        public int VendorId { get; set; }

        public string Name { get; set; }
    }

И наш новый тип
GeneratedTable
Код

    public class GeneratedTable
    {
        public string AppName { get; set; }
        public string VendorName { get; set; }
        public int VendorId { get; set; }
    }

Так же создана наша модель представления. Здесь находится логика поведения нашего окна  smile 
MainWindowViewModel
Код

public class MainWindowViewModel : INotifyPropertyChanged 
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private readonly IEnumerable<TableVendor> _vendors = null;

        private readonly IEnumerable<TableApplication> _applications = null;

        private readonly IEnumerable<GeneratedTable> _joinedTable = null;

        private int _selectedIndex = 0;

        //private string _outputText = "";

        public MainWindowViewModel()
        {
            _vendors = new List<TableVendor>()
                           {
                               new TableVendor() {VendorId = 0, Name = "Microsoft"},
                               new TableVendor() {VendorId = 1, Name = "Mozilla"},
                               new TableVendor() {VendorId = 2, Name = "Adobe"},
                               new TableVendor() {VendorId = 3, Name = "Kaspersky Lab"}
                           };


            _applications = new List<TableApplication>()
                                {
                                new TableApplication(){AppId = 0, Name = "MS Windows", VendorId = 0},
                                new TableApplication(){AppId = 1, Name = "MS Office", VendorId = 0},
                                new TableApplication(){AppId = 2, Name = "FireFox", VendorId = 1},
                                new TableApplication(){AppId = 3, Name = "Photoshop", VendorId = 2},
                                new TableApplication(){AppId = 4, Name = "AVP", VendorId = 3},
                                new TableApplication(){AppId = 5, Name = "KIS", VendorId = 3}
                                };

            _joinedTable = from app in _applications
                           join v in _vendors on app.VendorId equals v.VendorId
                           select new GeneratedTable() {AppName = app.Name, VendorName = v.Name, VendorId = v.VendorId};
        }

        public IEnumerable<GeneratedTable> JoinedTable
        {
            get { return _joinedTable; }
        }

        public int SelectedIndex
        {
            get { return _selectedIndex; }
            set
            {
                _selectedIndex = value;
                NotifyPropertyChanged("SelectedIndex");
                NotifyPropertyChanged("OutputText");
            }
        }

        public string OutputText
        {
            get
            {
                return _joinedTable.ToList()[SelectedIndex].AppName; 
            }
        }


        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    }

Ну и биндим свойства нашей модели представления к окну
Код

<Window x:Class="WpfApplication5.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:WpfApplication5.ViewModels"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <vm:MainWindowViewModel x:Key="viewModel" />
    </Window.Resources>
    <Grid>
        <StackPanel Orientation="Horizontal" VerticalAlignment="Top">
            <Label Content="Application Name :"/>
            <TextBox Height="23"  Name="nameTextBox" 
                     Text="{Binding Source={StaticResource viewModel}, 
                Path=OutputText, Mode=OneWay, 
                UpdateSourceTrigger=PropertyChanged}" Width="120" />
        </StackPanel>

        <StackPanel Margin="0,30" Orientation="Horizontal" VerticalAlignment="Top">
            <Label Content="Vendor Name:" Grid.Column="0" Grid.Row="0"/>
            <ComboBox Name="cbxVendorName" VerticalAlignment="Center" 
                      ItemsSource="{Binding Source={StaticResource viewModel}, 
                Path=JoinedTable, UpdateSourceTrigger=PropertyChanged}"
                      SelectedIndex="{Binding Source={StaticResource viewModel}, 
                Path=SelectedIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                      DisplayMemberPath="VendorName"
                      Width="120"/>
        </StackPanel>
        
    </Grid>
</Window>

Вот и всё  smile . Теперь сложное и запутанное стало более простым smile 

Присоединённый файл ( Кол-во скачиваний: 3 )
Присоединённый файл  WpfApplication5.zip 78,66 Kb


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
Kefir
Дата 19.6.2011, 07:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


«Hakuna Matata»
***


Профиль
Группа: Комодератор
Сообщений: 1878
Регистрация: 25.1.2003
Где: Tampere, Suomi

Репутация: 22
Всего: 87



Ronin08, что-то у нас с тобой понимания никак нет. Раз ты привязываешь текст текстбокса к Name, значит датаконтекст у текстбокса содержит Application, не? Значит можно привязаться к DataContext.VendorId.
PM MAIL WWW Skype   Вверх
Ronin08
Дата 19.6.2011, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 16.2.2008
Где: г.Москва

Репутация: нет
Всего: 1



Цитата

Раз ты привязываешь текст текстбокса к Name, значит датаконтекст у текстбокса содержит Application, не?

все верно, но разве таким способом Combobox узнает, что надо установить SelectedValue = Application.VendorId?
В общем так не работает

Rohoss, так я делал, но это не то! В твоем примере в комбобоксе получается записей столько сколько в списке List<TableApplication>, т.е. в комбобоксе мы видим

Microsoft
Microsoft
Mozilla
Adobe
Kaspersky Lab
Kaspersky Lab

а должно быть:

Microsoft
Mozilla
Adobe
Kaspersky Lab

--------------------
Зачем вставать рано или поздно? Надо вставать вовремя
PM MAIL   Вверх
Rohoss
Дата 19.6.2011, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Ну уж извини, но как ты себе это представляешь? Если в таком случае ты выберешь вендора, то какой по твоему продукт должен отображаться, если их несколько на одного вендора? В таком случае логично делать не текст бокс для имени приложения, а лист бокс.


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
Ronin08
Дата 19.6.2011, 15:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 16.2.2008
Где: г.Москва

Репутация: нет
Всего: 1



Возможно я не точно выразился
Цитата

нужно чтобы в combobox выделялась запись соответствующая Application.VendorId

здесь я подрозумевал, то что combobox это контрол для выбора Vendor для текущего Application, а не на оборот.
Например, по ошибке для  Application c Name="MS Windows" стоит вендор "Kaspersky Lab". Я открываю диалог редактирования Application
там есть combobox c записями

Microsoft
Mozilla
Adobe
Kaspersky Lab 

у устаноленным SelectedValue на "Kaspersky Lab", я меняю на Microsoft и у нас в Application.VendorId усанавливается новое значение вендора.
--------------------
Зачем вставать рано или поздно? Надо вставать вовремя
PM MAIL   Вверх
Rohoss
Дата 19.6.2011, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



В таком случае в чём вообще проблема? Биндь комбо бокс к таблице с вендорами!

Добавлено @ 15:55
Ronin08, я так понимаю, ты сам не знаешь чего хочешь? Мне кажется, в твоём случае, было бы целесообразно сделать так:
две таблицы: приложений и вендоров. два комбобокса, к одному биндится таблица приложений, к другому вендоры. Внизу лисбокс со списком всех приложений и вендоров.
логика такая: ты выбираешь приложение(в комбобоксе), в другом выбираешь вендора. Есть кнопка, при нажатии на которую вендор у приложения изменится(станет таким как в комбобоксе списка вендоров), и в результате также изменится его представление в листбоксе.
Это твой случай? Если да, то мне сложно понять с какого боку там делает текстовое поле. Или ты предлагаешь название приложения туда вручную вводить?

Это сообщение отредактировал(а) Rohoss - 19.6.2011, 15:56


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
Ronin08
Дата 19.6.2011, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 16.2.2008
Где: г.Москва

Репутация: нет
Всего: 1



Цитата

В таком случае в чём вообще проблема? Биндь комбо бокс к таблице с вендорами!

Rohoss, еще из моего вопроса(1- сообщение в этой теме) видно, что я так и делаю, но не знаю как правильно указать SelectedValue, чтобы он привязывался к Application.VendorId

Код

<CollectionViewSource x:Key="vendorViewSource" d:DesignSource="{d:DesignInstance my:Vendor, CreateList=True}" />

 <StackPanel Margin="0,30" Orientation="Horizontal" VerticalAlignment="Top"
                      DataContext="{StaticResource vendorViewSource}">
            <Label Content="Vendor Name:" Grid.Column="0" Grid.Row="0"/>
            <ComboBox Name="cbxVendorName" VerticalAlignment="Center" Width="120"
                      ItemsSource="{Binding}"
                      DisplayMemberPath="Name"/>
        </StackPanel>


Цитата

я так понимаю, ты сам не знаешь чего хочешь? 

 Знаю. Это стандартная логика, когда одно из свойств объекта мы можем выбрать из списка возможных свойств. Просто я хочу чтобы везде где возможно делать привязку данных в xaml. Это все элементарно делается в коде, просто намного больше писанины, да и вообще хочется разобраться.

Это сообщение отредактировал(а) Ronin08 - 19.6.2011, 16:32
--------------------
Зачем вставать рано или поздно? Надо вставать вовремя
PM MAIL   Вверх
Rohoss
Дата 19.6.2011, 16:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Цитата(Ronin08 @  19.6.2011,  16:32 Найти цитируемый пост)
Rohoss, еще из моего вопроса(1- сообщение в этой теме) видно, что я так и делаю, но не знаю как правильно указать SelectedValue, чтобы он привязывался к Application.VendorId

Тогда ты не ответил на вопрос

Цитата(Rohoss @  19.6.2011,  15:40 Найти цитируемый пост)
 Если да, то мне сложно понять с какого боку там делает текстовое поле. Или ты предлагаешь название приложения туда вручную вводить?




--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
Ronin08
Дата 19.6.2011, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 16.2.2008
Где: г.Москва

Репутация: нет
Всего: 1



Цитата

Если да, то мне сложно понять с какого боку там делает текстовое поле. Или ты предлагаешь название приложения туда вручную вводить?


Давай сначала. 
Я хочу добавить новое Application 
Открывается Окно, в нем есть Textbox и Combobox и Button
В Textbox пишу "MS Exchange 2010" в Combobox выбираю из списка  

(1)Mozilla
(2)Microsoft
(3)Adobe
(4)Kaspersky Lab 

нужную мне, т.е. "Microsoft" (здесь у меня уже есть объект Application {Name = "MS Exchange 2010", VendorId = 2} ) Нажимаю Button и эта запись сохраняется в базе!

Потом, например,  Microsoft продали MS Exchange 2010 Эдобу (мало ли)
Тогда я открываю Application с Name =  "MS Exchange 2010" в Combobox в данный момент выбрана запись "Microsoft", устанавливаю  "Adobe". Здесь уже Application {Name = "MS Exchange 2010", VendorId = 3} ) Нажимаю Button и эта запись апдейтится в базе!



--------------------
Зачем вставать рано или поздно? Надо вставать вовремя
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | WPF и Silverlight | Следующая тема »


 




[ Время генерации скрипта: 0.0708 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.