#wpf #xaml #c#-4.0 #entity-framework-4
#wpf #xaml #c #-4.0 #entity-framework-4
Вопрос:
У меня возникли проблемы с моим полем со списком. Я пытаюсь установить выделение во время выполнения, но привязка не работает.
public ICLINKDesignatorCandidate SelectedDesignator
SelectedDesignator.Designator = somevalue;
...
<ComboBox Grid.Row="4" DisplayMemberPath="DisplayName"
SelectedValuePath="{Binding Path=DesignatorId}"
SelectedItem="{Binding Path=SelectedDesignator}"
ItemsSource="{Binding DesignatorList}" />
Итак, я получаю ошибку привязки:
Ошибка пути к BindingExpression: свойство ‘DesignatorId’ не найдено в ‘object’ «TCard4312VM’ (hashCode =47413204)’. Выражение привязки: Path=DesignatorId; DataItem=’TCard4312VM’ (hashCode =47413204); целевой элемент — ‘ComboBox’ (Name=»); целевое свойство — ‘SelectedValuePath’ (тип ‘Строка’)
Итак, ПОЧЕМУ он смотрит на родительскую модель представления вместо объекта CLINKDesignatorCandidate?
Таким образом, SelectedValuePath просматривает модель родительского представления ВМЕСТО свойства элемента в списке назначений. Странно то, что когда мой список назначений представлял собой список типа «DESIGNATOR» (который был объектом entity framework), это работало отлично, и проблем с привязкой не было.
Очевидно, что DisplayName работает правильно, поэтому я не знаю, почему DesignatorID не работает. Вот класс:
public class CLINKDesignatorCandidate : ICLINKDesignatorCandidate
{
public CLINKDesignatorCandidate()
{
}
public int DesignatorID { get; set; }
public DESIGNATOR Designator
{
get;
set;
}
public string DisplayName
{
get;
set;
}
}
Вот код, который работал, когда я привязывался к списку обозначений типов (entity framework entity):
<ComboBox Grid.Row="3" IsEditable="True"
DisplayMemberPath="DesignatorName"
SelectedValuePath="{Binding Id}"
SelectedItem="{Binding SelectedDesignator}"
ItemsSource="{Binding DesignatorList}" />
Это работало отлично, и у меня никогда не возникало проблем с привязкой, когда он пытался искать «Id» в модели родительского представления.
Я устанавливаю модель представления в коде следующим образом:
public New4312(IEquipment4312VM vm)
: this()
{
InitializeComponent();
this.DataContext = vm;
}
Я использую DataTemplate в словаре ресурсов для поля со списком:
<DataTemplate x:Key="resTCard4312MIP">
<Button Tag="{Binding}" >
<Grid DataContext="{Binding}">
<telerik:Tile Width="100" Background="Purple">
<ComboBox Grid.Row="4" IsEditable="True"
DisplayMemberPath="DisplayName"
SelectedValuePath="{Binding Path=DesignatorId}"
SelectedValue="{Binding Path=SelectedDesignator.DesignatorID}"
SelectedItem="{Binding Path=SelectedDesignator}"
ItemsSource="{Binding DesignatorList}" />
</Grid>
</telerik:Tile>
etc...
Имейте в виду, что весь этот код работал, когда мой список назначений был списком объектов вместо пользовательского класса.
Спасибо за любую помощь. Надеюсь, я достаточно хорошо объяснил проблему.
Комментарии:
1. Форматируйте свои вопросы.
2. Что я неправильно отформатировал?
3. Вы видели все изменения? Пустые строки? Материал за пределами экрана.
4. Интересно, для меня это выглядит нормально. Ничего не исчезает с экрана.
5. Да, потому что он был отредактирован другими. Вернитесь к своему оригиналу. И в нем все еще есть пустые строки.
Ответ №1:
Идентификатор обозначения
это не то же самое, что
Идентификатор обозначения
Имена свойств чувствительны к регистру
XAML не соответствует имени свойства
Ответ №2:
SelectedValuePath
предполагается, что это строковое свойство, которое используется для определения имени свойства элементов, которые будут использоваться в качестве значения. Я думаю, что это используется reflection внутренне, но я не уверен.
Прямо сейчас вы привязываете это свойство к свойству вашего ComboBox.DataContext
, и похоже, что ваша ошибка привязки действительно верна: в DesignatorId
вашем ComboBox.DataContext
элементе нет свойства с именем, которое имеет тип TCard4312VM
Измените его с привязки на строку, и он должен работать
SelectedValuePath="DesignatorID"
Что касается того, почему ваш выбор работает неправильно, для этого может быть несколько причин.
-
Одна из распространенных, которые я вижу, заключается в том, что WPF может запутаться, когда вы привязываете более одного из
Selected
свойств (SelectedItem
,SelectedValue
иSelectedIndex
). Все 3 свойства устанавливают одно и то же, какой элемент выбран, однако я считаю, что нет определенного порядка, в котором они выполняются, и установка более одного может вызвать проблемы.Поскольку вы привязываетесь к пользовательскому объекту, я бы предложил удалить
SelectedItem
свойство и сохранить толькоSelectedValue
и (исправленные)SelectedValuePath
свойства. -
Вторая распространенная причина, по которой пользовательский элемент не выбирается, заключается в том, что WPF сравнивает
SelectedItem
с элементами вItemsSource
using.Equals
, который по умолчанию сравнивает объекты по ссылке. Итак, если вашаSelectedItem
ссылка точно такая же, как и у элемента вItemsSource
, это будет работать, однако, если это не так, он подумает, что элемент не найден, и ни один элемент не будет выбран.Общим решением в этом случае является либо использование
SelectedValue
andSelectedValuePath
для настройки выбранного элемента, либо переопределение.Equals()
и.GetHashCode()
вашего элемента, чтобы они считались равными на основе их данных, а не ссылки. -
И третья вещь, о которой я могу подумать, которая может быть причиной этого, я не вижу никаких уведомлений об изменениях в вашем коде. Возможно, вы оставили это для простоты, однако я часто вижу, как новые пользователи WPF забывают внедрить INotifyPropertyChanged, поэтому я подумал, что это стоит упомянуть. Уведомление PropertyChange отвечает за оповещение пользовательского интерфейса при изменении значения, чтобы он мог обновить любые привязки к этому свойству.
Ответ №3:
Итак, ПОЧЕМУ он смотрит на родительскую модель представления вместо объекта CLINKDesignatorCandidate?
Поскольку именно это происходит, если вы устанавливаете подобную привязку, только результат (путь к значению) будет оцениваться по элементам, а не привязка к свойствам пути.
Странно то, что когда мой список назначений представлял собой список типа «DESIGNATOR» (который был объектом entity framework), это работало отлично, и проблем с привязкой не было.
Почему-то я вам не верю. Источник элементов не должен влиять на фундаментальную механику работы системы привязки.