Выбранное значение WPF, несоответствие пути displaymember списку и полю со списком

#c# #wpf

#c# #wpf

Вопрос:

У меня есть хранимая процедура, вызываемая DropDownIndividuals() , которая была создана с использованием LINQ. Хранимая процедура возвращает FullName и Case_Number . Я хочу установить значение, SelectedValuePath равное Case_Number столбцу в моей хранимой процедуре. Вот как я сделал это для listbox, и это работает.

 private void listBox1_Loaded(object sender, RoutedEventArgs e){
    using (ToolboxDataContext toolboxDB = new ToolboxDataContext())//this is linq in action
    {
         var x = toolboxDB.DropDownIndividuals().ToList();//convert to a list
         listBox1.ItemsSource = x;  //bind the data 
         listBox1.SelectedValuePath = "Case_Number";
         listBox1.DisplayMemberPath = "FullName";

         Console.WriteLine(listBox1.SelectedValue.ToString());
         //Result:it shows the case number of the person the user picks.
    }
}
  

Теперь я делаю то же самое для выпадающего списка, И ЭТО НЕ РАБОТАЕТ.

 private void individualDropDown_Loaded(object sender, RoutedEventArgs e)
{
    using (ToolboxDataContext toolbox = new ToolboxDataContext())
    {
        var individualDropDownBox = toolbox.DropDownIndividuals().ToList();
        individualDropDown.ItemsSource = individualDropDownBox;
        individualDropDown.DisplayMemberPath = "FullName";
        individualDropDown.SelectedValuePath = "Case_Number";
        Console.WriteLine(individualDropDown.SelectedValue.ToString());
    }
}
  

Почему? Как я могу это исправить?

Комментарии:

1. «НЕ РАБОТАЕТ», Вы можете сделать лучше, чем это. Что не работает? Чего вы ожидали, и что произошло вместо этого? Люди с большей вероятностью помогут (и смогут помочь лучше), если вы объясните проблему.

2. Хорошо, когда я выбираю кого-то из поля со списком, он должен отображать case_number, например: Поле со списком имеет 2 значения «Джей» и «Родриго». Если я выберу Jay, в консоли должен отобразиться номер его обращения. Допустим, его номер обращения 54444.

3. что он делает вместо этого?

4. В нем говорится, что ссылка на объект не установлена для экземпляра объекта для линейной консоли. Строка записи (индивидуальный сброс. Выбранное значение. toString());

5. В любом случае, было бы достаточно знать, как добавить displaymemberpath и selectedvaluepath в поле со списком и как получить доступ к значениям в них.

Ответ №1:

Почему так хаотично? Вы даже не устанавливаете свойства в том же порядке, это эквивалентно:

 <Grid Margin="5">
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <ListBox Grid.Row="0" Grid.Column="0"
             Name="lbData" ItemsSource="{Binding DpData}"
             DisplayMemberPath="Name"
             SelectedValuePath="Id"/>
    <TextBlock Grid.Row="1" Grid.Column="0"
               Text="{Binding ElementName=lbData, Path=SelectedValue}"/>

    <ComboBox Grid.Row="0" Grid.Column="1" VerticalAlignment="Top"
              Name="cbData" ItemsSource="{Binding DpData}"
              DisplayMemberPath="Name"
              SelectedValuePath="Id"/>
    <TextBlock Grid.Row="1" Grid.Column="1"
               Text="{Binding ElementName=cbData, Path=SelectedValue}"/>
</Grid>
  

скриншот

… и он отображает тот же идентификатор, что и ожидалось.

Редактировать: При запуске выбранное значение обоих элементов управления является null кстати.

Комментарии:

1. в itemsource, если у меня есть класс linq с именем toolbox, в котором хранится моя процедура, называемая dropdownindividuals(), должен ли я указать Name =»lbData» ItemsSource=»{Binding Toolbox}» ??

2. Это не сработает, для привязки к набору объектов, которые извлекаются с помощью вызова метода, вы можете использовать ObjectDataProvider .

3. хорошо, я думаю, я изучу поставщика объектных данных и посмотрю, к чему это меня приведет. Я не понимаю, почему я должен делать это с помощью xaml, и я не могу просто привязать individualDropDown.DisplayMemberPath = «FullName»; непосредственно из codebehind.

4. На самом деле это не должно иметь значения. Вероятно, этому XAML просто все равно, находится ли значение null в какой-либо точке. Я только хотел проиллюстрировать, что у меня не было никаких проблем / я не мог видеть никакой разницы до сих пор. Почему бы вам просто не проверить наличие null перед вызовом ToString() ? (Редактировать: я только что проверил, и оба элемента управления имеют SelectedValue==null в начале)

5. да, это было бы null, потому что у вас нет подключения к базе данных для получения данных с sql server

Ответ №2:

Вы правы, существует своего рода несоответствие между способом, который SelectedValue обрабатывается для ListBox и ComboBox . Для ListBox , при загрузке, если у него есть фокус, SelectedValue будет соответствовать первому элементу в источнике данных. Для ComboBox даже если у него есть фокус и источник данных предоставляет элементы, значение по умолчанию SelectedValue будет сброшено во время Loaded обработки события.

Такое поведение является преднамеренным. Чтобы заставить ComboBox вести себя так, как ListBox установлено ComboBox.SelectedIndex в "0" там, где вы определяете ComboBox в XAML.

Комментарии:

1. <Выбранный индекс со списком = «0» Canvas.Left = «296» Canvas.Top = «6» Высота = «22» Имя = «individualDropDown» Ширина = «170» Видимость = «Скрытый» выпадающий список =»individualDropDown_DropDownOpened» /> Я все еще получаю проблему со ссылкой на объект

2. Закомментируйте инструкцию debug и просто запустите программу. Выбирается ли в поле со списком первое имя? Добавьте обработчик для individualDropDown_SelectionChanged , чтобы увидеть происходящие изменения.

Ответ №3:

Попробуйте это:

 MetroAreaList metroAreaList = _presenter.GetMetroArea();
foreach (MetroArea metroArea in metroAreaList) {
    lstMetroArea.DisplayMemberPath = "Name";
    lstMetroArea.SelectedValuePath = "ID";
    lstMetroArea.Items.Add(metroArea);
}
  

Это работает….

Ответ №4:

Ваш класс должен быть общедоступным:

 public class Place
{
    public string Name { get; set; }
    public string Id { get; set; }
}
foreach (var y in Lists)
{
    listBox1.DisplayMemberPath = "Name";
    listBox1.SelectedValuePath = "Id";
    // Console.WriteLine(y.Case_Number.ToString());
    listBox1.Items.Add(y);
}