我有一个 ListBox,它表示脚本语言中的文本行。我需要“单步执行”脚本,突出显示当前脚本行(比如绿色背景)。
模型视图有一个“CurrentLine”属性,它是当前行的索引,所以我想我会在 ItemContainerStyle 上编写一个触发器并使用转换器来确定列表框项的索引是否与 CurrentLine 相同。但是我正在努力将来自 VM 的当前行值传递给转换器,并且我不能将非常量值作为参数传递给转换器。我也不能用触发器的“值”这样做。我怎样才能传递这些值?
暴露为参考类型的电流
在我看来,修改 ViewModel 以将当前行保存为实际行LineViewModel
(或其他任何内容,取决于您的 VM 如何公开行),而不是选定的索引是更清洁的解决方案。
然后,您可以使用带有检查相等性的转换器的多重绑定来定义触发器:
<ListBox ItemsSource="{Binding Lines}" x:Name="List">
<ListBox.Resources>
<sample:EqualityConverter x:Key="Converter" />
</ListBox.Resources>
<ListBox.ItemContainerStyle>
<Style TargetType="Control">
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource Converter}">
<Binding Path="DataContext.CurrentLine" ElementName="List" />
<Binding />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="Blue"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
和转换器:
public class EqualityConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values[0] == values[1];
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
而已。
当前行显示为字符串(值类型)
如果您仍想使用整数索引,可以使用AlternationIndex
. 您将AlternationCount
列表的 设置为其项目数,以确保每个项目都有其唯一索引,然后绑定到ItemsSource.AlternationIndex
ListBoxItem 的附加属性。这样,您就不会混淆具有相同内容的行。
<ListBox ItemsSource="{Binding Resources}" x:Name="List" AlternationCount="{Binding Resources.Count}">
<ListBox.Resources>
<sample:EqualityConverter x:Key="Converter" />
</ListBox.Resources>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource Converter}">
<Binding Path="DataContext.CurrentItem" ElementName="List"/>
<Binding RelativeSource="{RelativeSource Self}" Path="(ItemsControl.AlternationIndex)"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="Blue"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
您需要稍微修改转换器:
public class EqualityConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return Equals(values[1], values[0] );
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}