Patrick Skelton Ответов: 2

Есть ли элегантный способ сделать записи списка редактируемыми в 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

Ладно, я понимаю. Я послал свой ответ как решение. Мне нужно уехать сегодня, но я буду здесь завтра, если у вас возникнут вопросы по поводу моего ответа.

2 Ответов

Рейтинг:
1

jimmson

Привет Патрик,

из нашего разговора я бы предложил использовать ItemsControl. Этот элемент управления WPF имеет свойство ItemsSource, которое вы можете привязать к своему списку клиентов/контактов, и его легко стилизовать и установить ItemTemplate. Это требует, чтобы научиться делать это, но это не трудно, и вы избавитесь от проблем, которые у вас есть с ListBox.

Класс ItemsControl (System.Окна.Управления)[^]
http://www.wpf-tutorial.com/list-controls/itemscontrol/[^]


Patrick Skelton

Тут я немного запутался. В приведенном выше руководстве говорится в конце: "Если вы хотите, чтобы пользователь мог выбирать элементы из списка, то вам лучше использовать один из других элементов управления, например ListBox или ListView." Мне действительно нужно сохранить представление о том, что у меня есть выбранный предмет. Извините, если я не совсем ясно выразился. Я исправлю первоначальный вопрос.

Кроме того, я уверен, что ItemsControl будет делать то, что я хочу, но у меня довольно мало времени (как и у всех нас), и я надеялся избежать такой кривой обучения.

Я думал, что нашел простое решение, которое я добавил к своему вопросу, и задаюсь вопросом, можете ли вы (или кто-то еще) определить, почему оно не работает?

jimmson

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

Patrick Skelton

Это странно. Что-то еще, должно быть, ломает его для меня, потому что я не могу редактировать текстовые поля. У меня есть решение, основанное на переключении шаблонов, которое привело меня туда большую часть пути. Я опубликую его, когда буду уверен, что он работает. Спасибо снова.

Рейтинг:
0

Pete O'Hanlon

Привет, Патрик - похоже, вы описываете сценарии, поддерживаемые IEditableCollectionView. Это позволяет переключаться назад и вперед между шаблоном отображения и редактируемым шаблоном. Я описываю, как с этим бороться здесь[^].


Patrick Skelton

Ух ты! Выглядит хорошо, но (я надеюсь) немного перебор на данный момент. Я поиграю с ним, когда у меня (а) будет немного больше времени или (б) наконец вырву свой последний клок волос.