Обновленное значение не отображается в пользовательском интерфейсе в WPF - PullRequest
0 голосов
/ 09 ноября 2019

Я пытаюсь динамически заполнить панель навигации в ListView

<ListView Background="Transparent" HorizontalAlignment="Center" x:Name="viewItemControl" ItemsSource="{Binding Views}">
        <ListView.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel/>
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>
        <ListView.ItemTemplate>
            <DataTemplate>
                <Button Style="{StaticResource PluginViewButton}" 
                        Command="{Binding ElementName=viewItemControl,Path=DataContext.NavigateCommand}" 
                        CommandParameter="{Binding ViewName}" 
                        BorderThickness="{Binding Path = ViewObj.DataContext.IsSelected, Converter={StaticResource BoolToThicknessConverter},Mode=OneWay}">
                    <Button.Content>
                        <Grid Background="White">
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition Height="15"/>
                            </Grid.RowDefinitions>
                            <Image Grid.Row="0" Source="{Binding Icon, Mode=OneTime}"></Image>
                            <TextBlock Grid.Row="1" Text="{Binding DisplayableName}" HorizontalAlignment="Center"/>
                        </Grid>
                    </Button.Content>
                </Button>
            </DataTemplate>
        </ListView.ItemTemplate>
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="Focusable" Value="false"/>
            </Style>
        </ListView.ItemContainerStyle>
    </ListView>

Представление списка привязано к коллекции объектов ViewInfo

public class ViewInfo
{
    public ViewInfo(IPluggableView view)
    {
        ViewName = view.ViewName;
        DisplayableName = view.DisplayableName;
        DisplayRank = view.DisplayRank;
        Icon = view.Icon;
        ViewModelType = view.ViewModelType;
        ViewObj = view;
    }
    public IPluggableView ViewObj { get; set; }
    public string ViewName { get; set; }
    public string DisplayableName { get; set; }
    public Type ViewModelType { get;set; }
    public int DisplayRank { get; set; }
    public BitmapSource Icon { get; set; }
}

Интерфейс IPluggableView реализованвсеми моими пользовательскими элементами управления, которые являются представлениями

Мой базовый класс viewmodel имеет свойство IsSelected . Класс Viewmodel реализует интерфейс призмы INavigationAware , поэтому в функциях OnNavigatedTo и OnNavigatedFrom я обновляю свойство IsSelected.

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

Navigation Panel

Итак, я написал конвертер BoolToThickness, который просто возвращает 0,5 или 2 в зависимости от значения.

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

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

1 Ответ

1 голос
/ 09 ноября 2019

Вы должны определить ItemContainerStyle и вызвать IsSelected напрямую. Переопределять ControlTemplate необходимо только в том случае, если вы хотите изменить или удалить поведение выделения по умолчанию:

<ListView.ItemContainerStyle>
  <Style TargetType="ListViewItem">
    <Setter Property="BorderThickness"
            Value="1" />
    <Setter Property="BorderBrush"
            Value="Black" />

    <!-- Optional -->
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="ListViewItem">
          <Border Background="{TemplateBinding Background}" 
                  BorderBrush="{TemplateBinding BorderBrush}"
                  BorderThickness="{TemplateBinding BorderThickness}" 
                  Padding="{TemplateBinding Padding}">
            <ContentPresenter />
          </Border>
        </ControlTemplate>
      </Setter.Value>
    </Setter>

    <!-- Change border thickness on item is selected -->
    <Style.Triggers>
      <Trigger Property="IsSelected" Value="True">
        <Setter Property="BorderThickness" Value="3" />
      </Trigger>
    </Style.Triggers>
  </Style>
</ListView.ItemContainerStyle>

Кроме того, вам необходимо привязать ListView.SelectedItem к вашей модели представления для управления текущим выбором.

Но если вы все еще хотите использовать преобразователь значений, вам следует настроить привязку на BorderThickness:

<Button BorderThickness="{Binding RelativeSource="{RelativeSource FindAncestor, AncestorType=ListViewItem}, Path=IsSelected, Converter={StaticResource BoolToThicknessConverter}}">
...