强制列表框在MVVM中更新

时间:2013-06-11 15:11:04

标签: c# wpf mvvm

我有一个列表框,其中包含要执行的脚本文件的行。我打算在脚本中的断点行显示红色,所以在列表框容器的样式中我有

<DataTrigger Value="True">
    <DataTrigger.Binding>
        <MultiBinding Converter="{StaticResource IsBreakpointLineConverter}">
            <Binding Path="DataContext" ElementName="scriptListBox"/>
            <Binding RelativeSource="{RelativeSource Self}" Path="(ItemsControl.AlternationIndex)"/>
        </MultiBinding>
    </DataTrigger.Binding>
    <Setter Property="Foreground" Value="Red"/>
</DataTrigger>

转换器IsBreakpointLineConverter将第一个参数作为我的ViewModel,它有一个方法GetCommandAtLineNumber(int line),第二个参数是脚本命令的行号:

public class IsBreakpointLineConverter : IMultiValueConverter
{
    public object Convert( object [] values, Type targetType, object parameter, CultureInfo culture )
    {
        ScriptViewModel svm = (ScriptViewModel)values[0];
        int line = (int)values[1];
        ScriptCommand command = svm.GetCommandAtLine( line );
        return command != null && command.IsBreakpoint;
    }

    public object[] ConvertBack( object value, Type[] targetType, object parameter, CultureInfo culture )
    {
        throw new NotSupportedException();
    }
}

我的ViewModel还实现了一个命令来切换命令的断点状态

    private void toggleBreakpoint( object arg )
    {
        Debug.Assert( _selectedCommand != null );

        SelectedLineIsBreakpoint = !SelectedLineIsBreakpoint;
    }

这很好用,但它不会更新ListBox。如果我选择一个新脚本,然后是旧脚本,则断点线显示为红色;因此,我需要一种方法来确保在切换断点行时刷新列表框内容。现在卡住了!

编辑如果我将以下可怕的黑客添加到toggleBreakpoint,事情会按预期运行:

    private void toggleBreakpoint( object arg )
    {
        Debug.Assert( _selectedCommand != null );

        SelectedLineIsBreakpoint = !SelectedLineIsBreakpoint;
        _scriptLines = new List<string>( _scriptLines );
        OnPropertyChanged( "ScriptLines" );
    }

1 个答案:

答案 0 :(得分:1)

IsBreakpoint的{​​{1}}属性发生更改时,您希望UI更改,但您没有绑定到此属性的任何内容。 ScriptCommand的{​​{1}}属性可能绑定到Model或ViewModel对象的集合。它是ItemsSource个对象的集合吗?您可以将ListBox属性转换为依赖项属性,并使用以下内容直接绑定到该属性:

ScriptCommand

如果向IsBreakpoint添加依赖项属性会破坏您的体系结构,则应添加一个新的ViewModel类来表示它。