更新后的值未反映在 WPF 的 UI 中
Updated value not reflecting in UI in WPF
我正在尝试在 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 由我的所有用户控件实现,它们是视图
我的视图模型基础 class 有一个 属性 IsSelected。
Viewmodel class 正在实现 prism INavigationAware 接口,因此在 OnNavigatedTo 和 OnNavigatedFrom 函数中我正在更新 IsSelected 属性.
我希望我的按钮边框在选择视图时变粗,并且当我导航到另一个视图时它应该恢复为默认值,如下所示。
所以我写了 BoolToThickness 转换器,它只是 returns 0.5 或 2,具体取决于值。
我面临的问题是它只在加载时更新一次,之后就再也没有更新过,尽管我更新了 IsSelected 属性。
我确定 UI 没有收到 RaisePropertyChanged 事件。但我知道如何解决这个问题。
如果这是设计问题,请帮我改正。
您应该直接定义 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}}">
我正在尝试在 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 由我的所有用户控件实现,它们是视图
我的视图模型基础 class 有一个 属性 IsSelected。 Viewmodel class 正在实现 prism INavigationAware 接口,因此在 OnNavigatedTo 和 OnNavigatedFrom 函数中我正在更新 IsSelected 属性.
我希望我的按钮边框在选择视图时变粗,并且当我导航到另一个视图时它应该恢复为默认值,如下所示。
所以我写了 BoolToThickness 转换器,它只是 returns 0.5 或 2,具体取决于值。
我面临的问题是它只在加载时更新一次,之后就再也没有更新过,尽管我更新了 IsSelected 属性。
我确定 UI 没有收到 RaisePropertyChanged 事件。但我知道如何解决这个问题。 如果这是设计问题,请帮我改正。
您应该直接定义 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}}">