Первоначальный фокус на ItemsControl - DataTemplate - PullRequest
0 голосов
/ 13 апреля 2020

У меня есть окно WPF, где я отображаю информацию о некоторых местах. Местоположения поступают из BindingList (AvailableLocations) и отображаются с помощью DataTemplate внутри ScrollViewer. Ниже приведен мой xaml-код.

<Border Margin="0" Background="White">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <TextBlock Text="Title" FontSize="14" FontWeight="Bold" Margin="10"/>
            <Button Content="X" HorizontalAlignment="Right" MinWidth="0" Grid.Column="1" Command="{Binding CancelCommand}" Margin="2.5" />
        </Grid>
        <Border Margin="10,0,10,10" BorderBrush="Black" BorderThickness="0.5" Grid.Row="1"  Background="GhostWhite">
            <ScrollViewer VerticalScrollBarVisibility="Auto" Margin="0,2.5,2.5,2.5"  IsTabStop="False" Focusable="False">
                <ItemsControl ItemsSource="{Binding AvailableLocations}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Button Content="{Binding Description}" Margin="0, 10" MinWidth="200">
                                <Button.Template>
                                    <ControlTemplate TargetType="Button">
                                        <Border x:Name="Border" Width="{TemplateBinding Width}"
                                        Height="{TemplateBinding Height}"
                                        Background="{TemplateBinding Background}"
                                        BorderBrush="Gray"
                                        BorderThickness="1">
                                            <Label x:Name="Content"  Content="{TemplateBinding Content}"
                                           FontWeight="{TemplateBinding FontWeight}"
                                           FontSize="{TemplateBinding FontSize}"/>
                                        </Border>
                                        <ControlTemplate.Triggers>
                                            <Trigger Property="IsMouseOver" Value="True">
                                                <Setter Property="Background" Value="LightGreen" TargetName="Border"/>
                                                <Setter Property="Cursor" Value="Hand"/>
                                            </Trigger>
                                            <Trigger Property="IsPressed" Value="True">
                                                <Setter Property="Background" Value="LightGreen" TargetName="Border"/>
                                                <Setter Property="BorderThickness" Value="2" TargetName="Border"/>
                                                <Setter Property="BorderBrush" Value="DarkGreen" TargetName="Border"/>
                                                <Setter Property="FontWeight" Value="SemiBold" TargetName="Content"/>
                                                <Setter Property="Cursor" Value="Hand"/>
                                            </Trigger>
                                        </ControlTemplate.Triggers>
                                    </ControlTemplate>
                                </Button.Template>
                            </Button>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                </ItemsControl>
            </ScrollViewer>
        </Border>
        <Button Name="btnCancel" Content="_Cancel" Command="{Binding CancelCommand}" IsCancel="True" Grid.Row="2"  Margin="10" HorizontalAlignment="right"  MinWidth="70"/>
    </Grid>

</Border>

А мои ViewModel и Model следующие:

class Window2ViewModel
{
    public BindingList<Location> AvailableLocations { get; private set; }
    public Window2ViewModel()
    {
        IList<Location> locations = new List<Location>()
        {
            new Location(){Description ="Desc 1"},
            new Location(){Description ="Desc 2"},
            new Location(){Description ="Desc 3"},
            new Location(){Description ="Desc 4"},
            new Location(){Description ="Desc 5"},
        };

        AvailableLocations = new BindingList<Location>(locations);
    }
}
public class Location
{
    public string Description { get; set; }
    public double LocationCD { get; set; }
    public string LocationType { get; set; }
    public double LocationTypeCd { get; set; }
    public string LocationTypeMean { get; set; }
    public double OrganizationID { get; set; }

} 

Я столкнулся с двумя проблемами здесь:

  1. Когда Я делаю вкладку, фокус переходит к контейнеру доступных элементов местоположений, и я хочу ограничить это. Я хочу, чтобы поля местоположения и кнопка были табулируемыми, а не элементами управления контейнером. Я попытался установить IsTabStop="False" Focusable="False" на ScrollViewer, но это не работает.
  2. Я хочу, чтобы начальная фокусировка окна была на первом поле местоположения (Des c 1 в данном случае). Я знаю, что для контроля уровня окна это может быть сделано FocusManager (FocusManager.FocusedElement="{Binding ElementName=controlName}. Но я не знаю, как это можно сделать для элементов внутри DataTemplate.

Надеюсь, вы, ребята, понимаете проблемы, с которыми я сталкиваюсь, и любая помощь в этом будет высоко оценена.

Заранее спасибо

1 Ответ

0 голосов
/ 15 апреля 2020

После долгих проб и ошибок я понял, что в центре внимания нет ни элементов Border, ни элементов ScrollViewer. Основное внимание уделяется элементу ItemsControl. Поэтому установка IsTabStop = False на ItemsControl решила мою первую проблему.

Для первоначального сосредоточения на элементе DataTemplate я не смог найти никаких прямых исправлений. Но, используя следующий код, я смог сосредоточиться на первом элементе внутри моего DataTemplate.

Loaded += (s, e) =>
              {
                  foreach (var item in itemCtrl.Items)
                  {
                      UIElement uiElement =
                          (UIElement)itemCtrl.ItemContainerGenerator.ContainerFromItem(item);
                      if (uiElement != null)
                      {
                          if (uiElement is ContentPresenter)
                          {
                              ContentPresenter c = (uiElement as ContentPresenter);
                              Button b = c.ContentTemplate.FindName("btn", c) as Button;

                              Dispatcher.BeginInvoke(new Action(() =>
                              {
                                  b.Focus();
                              }), DispatcherPriority.Normal);

                              return;
                          }
                      }
                  }
              };

Я не уверен, можно ли сделать это непосредственно внутри xaml. Надеюсь, кто-нибудь найдет более подходящее решение. В настоящее время исправление выше работает для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...