我有一个列表框,其中包含要执行的脚本文件的行。我打算脚本中的断点行显示为红色,所以在我得到的列表框容器的样式中
<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。如果我选择一个新脚本,然后选择旧脚本,断点行显示为红色;因此,我需要一种方法来确保在切换断点行时刷新列表框内容。现在卡住了!
编辑如果我添加以下可怕的黑客来切换断点,事情会按预期工作:
private void toggleBreakpoint( object arg )
{
Debug.Assert( _selectedCommand != null );
SelectedLineIsBreakpoint = !SelectedLineIsBreakpoint;
_scriptLines = new List<string>( _scriptLines );
OnPropertyChanged( "ScriptLines" );
}