3

我有一个 ListBox,它表示脚本语言中的文本行。我需要“单步执行”脚本,突出显示当前脚本行(比如绿色背景)。

模型视图有一个“CurrentLine”属性,它是当前行的索引,所以我想我会在 ItemContainerStyle 上编写一个触发器并使用转换器来确定列表框项的索引是否与 CurrentLine 相同。但是我正在努力将来自 VM 的当前行值传递给转换器,并且我不能将非常量值作为参数传递给转换器。我也不能用触发器的“值”这样做。我怎样才能传递这些值?

4

1 回答 1

3

暴露为参考类型的电流

在我看来,修改 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.AlternationIndexListBoxItem 的附加属性。这样,您就不会混淆具有相同内容的行。

<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();
    }
}
于 2013-06-05T10:28:11.210 回答