我有一个列表框,其中包含要执行的脚本文件的行。我打算在脚本中的断点行显示红色,所以在列表框容器的样式中我有
<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" );
}
答案 0 :(得分:1)
当IsBreakpoint
的{{1}}属性发生更改时,您希望UI更改,但您没有绑定到此属性的任何内容。 ScriptCommand
的{{1}}属性可能绑定到Model或ViewModel对象的集合。它是ItemsSource
个对象的集合吗?您可以将ListBox
属性转换为依赖项属性,并使用以下内容直接绑定到该属性:
ScriptCommand
如果向IsBreakpoint
添加依赖项属性会破坏您的体系结构,则应添加一个新的ViewModel类来表示它。