Есть ли элегантный способ сделать записи списка редактируемыми в WPF?
У меня есть то, что, как я уверен, является чрезвычайно распространенным требованием, но поиск в Google до сих пор не дал мне ни малейшего представления о самом аккуратном способе изготовления предметов a
ListBox
редактируемый на месте.Обратите внимание, что мне все еще требуется понятие выбранного в данный момент элемента для элементов в списке.
У меня есть
ListBox
определяется следующим образом:<DataTemplate x:Key="DataTemplateContact"> <Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <TextBlock Grid.Row="0" Grid.Column="0" Text="Name:"/> <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding FullName}"/> <TextBlock Grid.Row="1" Grid.Column="0" Text="Telephone:"/> <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding MainTelephoneNumber}"/> </Grid> </DataTemplate> <ListBox ItemsSource="{Binding Contacts}" ItemTemplate="{StaticResource DataTemplateContact}"/>
Если я нажимаю на "мертвую" часть элемента, включается механизм изменения выбора WPF и устанавливает текущий выбранный элемент, что очень здорово. Проблема в том, что если я нажму на любой из
TextBox
управления. Я могу начать печатать в этих полях, но, насколько я могу судить, WPF, похоже, не осознает, что я что-то делаю.Если я поставлю
IsEnabled="False"
на TextBox
поля, то это устраняет часть проблемы. Если я нажму на TextBox
, WPF распознает, что выбранный в данный момент элемент изменился, и это устанавливается соответствующим образом в моей модели представления. Тогда возникает проблема, как определить, когда редактируемый в данный момент элемент в ListBox
терять фокус.Может ли кто-нибудь указать мне на аккуратное решение? Может быть, я могу что-то сделать с помощью триггеров?
Любая помощь была бы очень признательна.
Добрые пожелания ~ Патрик
Что я уже пробовал:
Я наполовину собрал что-то вместе, обрабатывая множество событий в пользовательском интерфейсе (например,
ListBox.SelectionChanged
, ListBox.MouseDoubleclick
, и пытается поймать клики в любом другом месте окна), но все это кажется очень неряшливым и ставит неудобное количество логики в мой кодовый файл XAML.Я недавно попробовал это сделать:
<Style x:Key="TestStyle" TargetType="TextBox"> <Setter Property="Focusable" Value="False"/> <Style.Triggers> <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" Value="True"> <Setter Property="Background" Value="Crimson"/> <Setter Property="Focusable" Value="True"/> </DataTrigger> </Style.Triggers> </Style>
Малиновый цвет установлен нормально, но текстовое поле не становится редактируемым. Кто-нибудь может объяснить, почему?
jimmson
Привет, Патрик. Судя по вашему описанию, я не уверен, действительно ли ListBox-это то, что вы ищете. Какие именно функции ListBox вам нужны?
Patrick Skelton
Привет.
Боюсь, мой выбор был основан просто на том факте, что я не знал, что есть альтернатива. Этот список не является частью главного детального представления или чего-то подобного. На экране слева отображается один клиент, а справа-список его контактов. Проверка правильности отображения списка контактов для клиента уже работает нормально, поэтому фактический список контактов можно рассматривать как существующий изолированно, если это имеет смысл.
jimmson
На мой взгляд, список был бы очень плохим выбором. Есть лучшие альтернативы, но это зависит от многих факторов. Первое - нужно ли повторно использовать этот элемент управления в других частях вашего приложения?
Patrick Skelton
Всегда есть вероятность, что мне может понадобиться та же функциональность в другом месте, но пока это одноразовый вариант в этом приложении. Если мне понадобится использовать его повторно, я позабочусь об этом позже. Надеюсь, к тому времени у меня будет лучшее понимание всего этого.
jimmson
Ладно, я понимаю. Я послал свой ответ как решение. Мне нужно уехать сегодня, но я буду здесь завтра, если у вас возникнут вопросы по поводу моего ответа.