Вложенные свойства со списком в DisplayMemberPath

#c# #wpf #xaml #data-binding

#c# #wpf #xaml #привязка к данным

Вопрос:

Я пытаюсь понять, почему это работает:

 <ComboBox Name="cboServer" HorizontalAlignment="Left" ItemsSource="{Binding Server.Connections}" DisplayMemberPath="ConnectionName" Margin="91,43,0,0" VerticalAlignment="Top" Width="279"/>
 

Но это не:

 <ComboBox Name="cboServer" HorizontalAlignment="Left" ItemsSource="{Binding Server}" DisplayMemberPath="Connections.ConnectionName" Margin="91,43,0,0" VerticalAlignment="Top" Width="279"/>
 

Причина этого в том, что я хочу привязать SelectedValue свойство ComboBox back к моей модели, но я не могу, если не смогу получить доступ Server ко всему в целом.

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

1. Используйте SelectedItem. Когда источник элемента привязан к серверам, тогда объект является объектом сервера со многими подключениями, и он не знает, какое имя показывать / отображать. Привязка к соединениям тогда есть свойство connectionName, которое также работает

2. Спасибо — не должен ли тот факт, что я указал «Соединения. connectionName» поэтому он будет знать, что отображать? Но это не так.

3. Нет! Предположим, у вас есть объект server, и этот сервер имеет 3 соединения, теперь какое имя он должен отображать?

4. Хорошо, это начинает иметь смысл, но тогда как ItemsSource=»{Сервер привязки. Соединения}» есть ли разница? Это работает, как и ожидалось.

5. У вашего DataContext есть свойство сервера, у этого сервера есть коллекция подключений. Вот почему вы можете привязываться к серверу. Соединения. Означает, что каждый элемент в ComboBox будет объектом соединения. Если вы, с другой стороны, привязываетесь к серверу, то в вашем ComboBox есть только один объект server, и DisplayMemberPath не может преобразовать соединение. Имя подключения к любому свойству в объекте сервера.

Ответ №1:

Документация для DisplayMemberPath состояний:

Возвращает или задает путь к значению в исходном объекте, который будет служить визуальным представлением объекта.

Это свойство ссылается на путь к свойству для типа элемента связанной коллекции.

 <ComboBox Name="cboServer" HorizontalAlignment="Left" ItemsSource="{Binding Server.Connections}" DisplayMemberPath="ConnectionName" Margin="91,43,0,0" VerticalAlignment="Top" Width="279"/>
 

Теперь первый вариант связывает коллекцию Connection объектов (я полагаю, может быть другого типа), а именно Server.Connections коллекцию. Connection Тип предоставляет свойство ConnectionName , которое может быть указано в качестве элемента для отображения в ComboBox .

Если Connection бы у него было свойство, например MyProvider , типа Provider , которое предоставляет Name свойство, тогда это DisplayMemberPath="Provider.Name" тоже было бы прекрасно.

 <ComboBox Name="cboServer" HorizontalAlignment="Left" ItemsSource="{Binding Server}" DisplayMemberPath="Connections.ConnectionName" Margin="91,43,0,0" VerticalAlignment="Top" Width="279"/>
 

Второй вариант отличается тем, что он связывает коллекцию Server . Если это не коллекция, вы получите ошибку привязки в вашем выводе, независимо от DisplayMemberPath .

Предположим, что это коллекция любого типа. Затем этот тип имеет свойство коллекции Connections с объектами типа Connection , которые снова имеют свойство ConnectionName . Путь отображения не имеет способа узнать, к какому конкретному элементу в Connections коллекции вы ссылаетесь. Итак, что ConnectionName он должен отображать: первый, второй, 42-й?

Сама коллекция, которая является List<Connection> или ObservableCollection<Connection> или чем-либо еще, не предоставляет a ConnectionName , поскольку она не является a Connection . Это разные типы, следовательно, путь к свойству недопустим.

Вы можете подтвердить это самостоятельно, явно сославшись на элемент, что можно сделать с помощью индексатора или косой черты в синтаксисе привязки, см. Синтаксис пути привязки для справки.

 <ComboBox Name="cboServer" HorizontalAlignment="Left" ItemsSource="{Binding Server}" DisplayMemberPath="Connections[2].ConnectionName" Margin="91,43,0,0" VerticalAlignment="Top" Width="279"/>
 

Это отобразило ConnectionName бы третье Connection . Ваши примеры не эквивалентны.