diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..fa46e28 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,148 @@ +# Top-most EditorConfig file +root = true + +# All generic files should use MSDOS style endings, not Unix (lf) +[*] +end_of_line = crlf +indent_style = tab +indent_size = 4 +guidelines = 110 + +[*.{ps1,psd1,psm1}] +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true +[*.il] +indent_style = space +indent_size = 2 +[*.{yml,yaml}] +indent_style = space +indent_size = 2 +[*.csproj] +indent_style = space +indent_size = 2 +[*.config] +indent_style = space +indent_size = 2 +[*.nuspec] +indent_style = space +indent_size = 2 +[*.vsixmanifest] +indent_style = space +indent_size = 2 +[*.vsct] +indent_style = space +indent_size = 2 +[*.md] +indent_style = space +indent_size = 2 + +[*.{cs,csx}] +tab_width = 4 +indent_size = 4 +indent_style = tab +end_of_line = crlf +charset = utf-8-bom +trim_trailing_whitespace = true +insert_final_newline = true + +# New line preferences +csharp_new_line_before_open_brace = methods, types, control_blocks, local_functions +csharp_new_line_before_else = true +csharp_new_line_before_catch = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_object_initializers = false +csharp_new_line_before_members_in_anonymous_types = false +csharp_new_line_within_query_expression_clauses = false + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = false +csharp_indent_switch_labels = true +csharp_indent_labels = one_less + +# Avoid 'this.' in generated code unless absolutely necessary, but allow developers to use it +dotnet_style_qualification_for_field = false:silent +dotnet_style_qualification_for_property = false:silent +dotnet_style_qualification_for_method = false:silent +dotnet_style_qualification_for_event = false:silent + +# Do not use 'var' when generating code, but allow developers to use it +csharp_style_var_for_built_in_types = false:silent +csharp_style_var_when_type_is_apparent = false:silent +csharp_style_var_elsewhere = false:silent + +# Use language keywords instead of BCL types when generating code, but allow developers to use either +dotnet_style_predefined_type_for_locals_parameters_members = true:silent +dotnet_style_predefined_type_for_member_access = true:silent + +# Using directives +dotnet_sort_system_directives_first = true +dotnet_separate_import_directive_groups = true + +# Wrapping +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = false + +# Code style +csharp_prefer_braces = true:silent + +# Expression-level preferences +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion + +# Expression-bodied members +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_accessors = true:silent + +# Pattern matching +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion + +# Null checking preferences +csharp_style_throw_expression = true:suggestion +csharp_style_conditional_delegate_call = true:suggestion + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = do_not_ignore +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +## Suppressions for ILSpy coding style + +# IDE2002:Consecutive braces must not have blank line between them +dotnet_diagnostic.IDE2002.severity = none + +# IDE2003: Blank line required between block and subsequent statement +# dotnet_diagnostic.IDE2003.severity = error +dotnet_style_allow_statement_immediately_after_block_experimental = false:none +dotnet_diagnostic.IDE2003.severity = none diff --git a/Directory.Build.props b/Directory.Build.props index 9825edd..5531e93 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -5,8 +5,8 @@ - 0.10.13 - 0.10.12.2 + 11.0.0 + 11.0.0 diff --git a/ILSpy.Core/AvalonEdit/TextMarkerService.cs b/ILSpy.Core/AvalonEdit/TextMarkerService.cs index e31d3b6..b06d0d8 100644 --- a/ILSpy.Core/AvalonEdit/TextMarkerService.cs +++ b/ILSpy.Core/AvalonEdit/TextMarkerService.cs @@ -111,9 +111,8 @@ public void Remove(ITextMarker marker) /// internal void Redraw(ISegment segment) { - textView.Redraw(segment, DispatcherPriority.Normal); - if (RedrawRequested != null) - RedrawRequested(this, EventArgs.Empty); + textView.Redraw(segment); + RedrawRequested?.Invoke(this, EventArgs.Empty); } public event EventHandler RedrawRequested; @@ -137,7 +136,7 @@ protected override void ColorizeLine(DocumentLine line) Math.Min(marker.EndOffset, lineEnd), element => { if (foregroundBrush != null) { - element.TextRunProperties.ForegroundBrush = foregroundBrush; + element.TextRunProperties.SetForegroundBrush(foregroundBrush); } // TODO: change font style //string tf = element.TextRunProperties.Typeface; diff --git a/ILSpy.Core/ContextMenuEntry.cs b/ILSpy.Core/ContextMenuEntry.cs index 8fd414d..a6be14a 100644 --- a/ILSpy.Core/ContextMenuEntry.cs +++ b/ILSpy.Core/ContextMenuEntry.cs @@ -181,9 +181,10 @@ void treeView_ContextMenuOpening(object sender, CancelEventArgs e) e.Cancel = true; // don't show the menu return; } + ContextMenu menu = (ContextMenu)sender; - if (ShowContextMenu(context, out IEnumerable items)) - menu.Items = items; + if (ShowContextMenu(context, out IEnumerable items)) + menu.ItemsSource = items; else // hide the context menu. e.Cancel = true; @@ -193,8 +194,8 @@ void textView_ContextMenuOpening(object sender, CancelEventArgs e) { TextViewContext context = TextViewContext.Create(textView: textView); ContextMenu menu = (ContextMenu)sender; - if (ShowContextMenu(context, out IEnumerable items)) - menu.Items = items; + if (ShowContextMenu(context, out IEnumerable items)) + menu.ItemsSource = items; else // hide the context menu. e.Cancel = true; @@ -204,16 +205,16 @@ void listBox_ContextMenuOpening(object sender, CancelEventArgs e) { TextViewContext context = TextViewContext.Create(listBox: listBox); ContextMenu menu = (ContextMenu)sender; - if (ShowContextMenu(context, out IEnumerable items)) - menu.Items = items; + if (ShowContextMenu(context, out IEnumerable items)) + menu.ItemsSource = items; else // hide the context menu. e.Cancel = true; } - bool ShowContextMenu(TextViewContext context, out IEnumerable menuItems) + bool ShowContextMenu(TextViewContext context, out IEnumerable menuItems) { - List items = new List(); + List items = new List(); foreach (var category in entries.OrderBy(c => c.Metadata.Order).GroupBy(c => c.Metadata.Category)) { bool needSeparatorForCategory = items.Count > 0; foreach (var entryPair in category) { @@ -223,6 +224,7 @@ bool ShowContextMenu(TextViewContext context, out IEnumerable menuItem items.Add(new Separator()); needSeparatorForCategory = false; } + MenuItem menuItem = new MenuItem(); menuItem.Header = MainWindow.GetResourceString(entryPair.Metadata.Header); if (!string.IsNullOrEmpty(entryPair.Metadata.Icon)) { @@ -232,6 +234,7 @@ bool ShowContextMenu(TextViewContext context, out IEnumerable menuItem Source = Images.LoadImage(entry, entryPair.Metadata.Icon) }; } + if (entryPair.Value.IsEnabled(context)) { menuItem.Click += delegate { entry.Execute(context); }; } else @@ -240,6 +243,7 @@ bool ShowContextMenu(TextViewContext context, out IEnumerable menuItem } } } + menuItems = items; return items.Count > 0; } diff --git a/ILSpy.Core/Controls/CustomDialog.xaml.cs b/ILSpy.Core/Controls/CustomDialog.xaml.cs index 393c332..c8d23fb 100644 --- a/ILSpy.Core/Controls/CustomDialog.xaml.cs +++ b/ILSpy.Core/Controls/CustomDialog.xaml.cs @@ -57,7 +57,7 @@ public CustomDialog(string caption, string message, int acceptButton = -1, int c this.WindowStartupLocation = WindowStartupLocation.CenterOwner; this.Width = buttonLabels.Length * (100+ 10); - buttons.Items = buttonLabels; + buttons.ItemsSource = buttonLabels; label.Text = message; diff --git a/ILSpy.Core/Controls/DialogWindow.cs b/ILSpy.Core/Controls/DialogWindow.cs index 99862ea..2324f59 100644 --- a/ILSpy.Core/Controls/DialogWindow.cs +++ b/ILSpy.Core/Controls/DialogWindow.cs @@ -1,10 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Reactive.Linq; -using System.Text; -using System.Threading.Tasks; -using Avalonia; using Avalonia.Controls; using Avalonia.Input; using Avalonia.Styling; diff --git a/ILSpy.Core/Controls/ResourceObjectTable.xaml.cs b/ILSpy.Core/Controls/ResourceObjectTable.xaml.cs index cfade13..24248d9 100644 --- a/ILSpy.Core/Controls/ResourceObjectTable.xaml.cs +++ b/ILSpy.Core/Controls/ResourceObjectTable.xaml.cs @@ -42,7 +42,7 @@ public partial class ResourceObjectTable : UserControl, IRoutedCommandBindable public ResourceObjectTable(IEnumerable resources, ContentPresenter contentPresenter) { InitializeComponent(); - resourceListView.Items = resources; + resourceListView.ItemsSource = resources; } private void InitializeComponent() @@ -67,7 +67,10 @@ void ExecuteCopy(object sender, ExecutedRoutedEventArgs args) { sb.AppendLine(item.ToString()); } - App.Current.Clipboard.SetTextAsync(sb.ToString()); + + //// App.Current.Clipboard.SetTextAsync(sb.ToString()); + var clipboard = TopLevel.GetTopLevel(this)?.Clipboard; + clipboard.SetTextAsync(sb.ToString()); } void CanExecuteCopy(object sender, CanExecuteRoutedEventArgs args) @@ -75,4 +78,4 @@ void CanExecuteCopy(object sender, CanExecuteRoutedEventArgs args) args.CanExecute = true; } } -} \ No newline at end of file +} diff --git a/ILSpy.Core/Controls/ResourceStringTable.xaml.cs b/ILSpy.Core/Controls/ResourceStringTable.xaml.cs index e075def..583e531 100644 --- a/ILSpy.Core/Controls/ResourceStringTable.xaml.cs +++ b/ILSpy.Core/Controls/ResourceStringTable.xaml.cs @@ -44,7 +44,7 @@ public partial class ResourceStringTable : UserControl, IRoutedCommandBindable public ResourceStringTable(IEnumerable strings, ContentPresenter contentPresenter) { InitializeComponent(); - resourceListView.Items = strings; + resourceListView.ItemsSource = strings; } private void InitializeComponent() @@ -69,7 +69,10 @@ void ExecuteCopy(object sender, ExecutedRoutedEventArgs args) { sb.AppendLine(item.ToString()); } - App.Current.Clipboard.SetTextAsync(sb.ToString()); + + ////App.Current.Clipboard.SetTextAsync(sb.ToString()); + var clipboard = TopLevel.GetTopLevel(this)?.Clipboard; + clipboard.SetTextAsync(sb.ToString()); } void CanExecuteCopy(object sender, CanExecuteRoutedEventArgs args) @@ -77,4 +80,4 @@ void CanExecuteCopy(object sender, CanExecuteRoutedEventArgs args) args.CanExecute = true; } } -} \ No newline at end of file +} diff --git a/ILSpy.Core/Controls/SearchBox.cs b/ILSpy.Core/Controls/SearchBox.cs index f831c61..f887fd0 100644 --- a/ILSpy.Core/Controls/SearchBox.cs +++ b/ILSpy.Core/Controls/SearchBox.cs @@ -34,9 +34,9 @@ public class SearchBox : TextBox { #region Dependency properties - public static StyledProperty SearchIconProperty = AvaloniaProperty.Register(nameof(SearchIcon)); + public static StyledProperty SearchIconProperty = AvaloniaProperty.Register(nameof(SearchIcon)); - public static StyledProperty ClearSearchIconProperty = AvaloniaProperty.Register(nameof(ClearSearchIcon)); + public static StyledProperty ClearSearchIconProperty = AvaloniaProperty.Register(nameof(ClearSearchIcon)); public static StyledProperty WatermarkColorProperty = AvaloniaProperty.Register(nameof(WatermarkColor)); @@ -65,13 +65,13 @@ public TimeSpan UpdateDelay set { SetValue(UpdateDelayProperty, value); } } - public IBitmap SearchIcon + public Bitmap SearchIcon { get { return GetValue(SearchIconProperty); } set { SetValue(SearchIconProperty, value); } } - public IBitmap ClearSearchIcon + public Bitmap ClearSearchIcon { get { return GetValue(ClearSearchIconProperty); } set { SetValue(ClearSearchIconProperty, value); } @@ -99,9 +99,9 @@ protected override void OnApplyTemplate(TemplateAppliedEventArgs e) } } - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) - { - base.OnPropertyChanged(change); + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); if (change.Property == TextProperty) { diff --git a/ILSpy.Core/CreateListDialog.xaml.cs b/ILSpy.Core/CreateListDialog.xaml.cs index 73799e9..3f9a2f4 100644 --- a/ILSpy.Core/CreateListDialog.xaml.cs +++ b/ILSpy.Core/CreateListDialog.xaml.cs @@ -39,7 +39,7 @@ private void InitializeComponent() //ListName.TextInput += TextBox_TextChanged; ListName.GetObservable(TextBox.TextProperty).Subscribe(text => TextBox_TextChanged(this, new TextInputEventArgs{Text = text})); - TemplateApplied += (sender, e) => Application.Current.FocusManager.Focus(ListName); + TemplateApplied += (sender, e) => ListName.Focus(); } private void TextBox_TextChanged(object sender, TextInputEventArgs e) @@ -69,4 +69,4 @@ public string NewListName } } -} \ No newline at end of file +} diff --git a/ILSpy.Core/DebugSteps.xaml.cs b/ILSpy.Core/DebugSteps.xaml.cs index 5a75367..364815f 100644 --- a/ILSpy.Core/DebugSteps.xaml.cs +++ b/ILSpy.Core/DebugSteps.xaml.cs @@ -68,7 +68,7 @@ private void WritingOptions_PropertyChanged(object sender, System.ComponentModel private void SelectionChanged(object sender, SelectionChangedEventArgs e) { Dispatcher.UIThread.InvokeAsync(() => { - tree.Items = null; + tree.ItemsSource = null; lastSelectedStep = int.MaxValue; }); } @@ -94,7 +94,7 @@ private void ILAstStepperUpdated(object sender, EventArgs e) #if DEBUG if (language == null) return; Dispatcher.UIThread.InvokeAsync(() => { - tree.Items = language.Stepper.Steps; + tree.ItemsSource = language.Stepper.Steps; lastSelectedStep = int.MaxValue; }); #endif @@ -164,4 +164,4 @@ private void tree_KeyDown(object sender, KeyEventArgs e) } } } -} \ No newline at end of file +} diff --git a/ILSpy.Core/ISmartTextOutput.cs b/ILSpy.Core/ISmartTextOutput.cs index 9e4399e..2e84b29 100644 --- a/ILSpy.Core/ISmartTextOutput.cs +++ b/ILSpy.Core/ISmartTextOutput.cs @@ -36,7 +36,7 @@ public interface ISmartTextOutput : ITextOutput /// /// Inserts an interactive UI element at the current position in the text output. /// - void AddUIElement(Func element); + void AddUIElement(Func element); void BeginSpan(HighlightingColor highlightingColor); void EndSpan(); @@ -47,7 +47,7 @@ public static class SmartTextOutputExtensions /// /// Creates a button. /// - public static void AddButton(this ISmartTextOutput output, IBitmap icon, string text, EventHandler click) + public static void AddButton(this ISmartTextOutput output, Bitmap icon, string text, EventHandler click) { output.AddUIElement( delegate { @@ -67,6 +67,7 @@ public static void AddButton(this ISmartTextOutput output, IBitmap icon, string } else { button.Content = text; } + button.Click += click; return button; }); diff --git a/ILSpy.Core/Images/Images.cs b/ILSpy.Core/Images/Images.cs index e09f3c2..1e9a67a 100644 --- a/ILSpy.Core/Images/Images.cs +++ b/ILSpy.Core/Images/Images.cs @@ -27,83 +27,82 @@ namespace ICSharpCode.ILSpy { static class Images { - static IBitmap LoadBitmap(string name) + static Bitmap LoadBitmap(string name) { Bitmap image = new Bitmap("Images/" + name + ".png"); //image.Freeze(); return image; } - public static readonly IBitmap Breakpoint = LoadBitmap("Breakpoint"); - public static readonly IBitmap CurrentLine = LoadBitmap("CurrentLine"); + public static readonly Bitmap Breakpoint = LoadBitmap("Breakpoint"); + public static readonly Bitmap CurrentLine = LoadBitmap("CurrentLine"); - public static readonly IBitmap ViewCode = LoadBitmap("ViewCode"); - public static readonly IBitmap Save = LoadBitmap("SaveFile"); - public static readonly IBitmap OK = LoadBitmap("OK"); + public static readonly Bitmap ViewCode = LoadBitmap("ViewCode"); + public static readonly Bitmap Save = LoadBitmap("SaveFile"); + public static readonly Bitmap OK = LoadBitmap("OK"); - public static readonly IBitmap Delete = LoadBitmap("Delete"); - public static readonly IBitmap Search = LoadBitmap("Search"); + public static readonly Bitmap Delete = LoadBitmap("Delete"); + public static readonly Bitmap Search = LoadBitmap("Search"); - public static readonly IBitmap Assembly = LoadBitmap("Assembly"); - public static readonly IBitmap AssemblyWarning = LoadBitmap("AssemblyWarning"); - public static readonly IBitmap AssemblyLoading = LoadBitmap("FindAssembly"); + public static readonly Bitmap Assembly = LoadBitmap("Assembly"); + public static readonly Bitmap AssemblyWarning = LoadBitmap("AssemblyWarning"); + public static readonly Bitmap AssemblyLoading = LoadBitmap("FindAssembly"); - public static readonly IBitmap Library = LoadBitmap("Library"); - public static readonly IBitmap Namespace = LoadBitmap("NameSpace"); + public static readonly Bitmap Library = LoadBitmap("Library"); + public static readonly Bitmap Namespace = LoadBitmap("NameSpace"); - public static readonly IBitmap ReferenceFolderOpen = LoadBitmap("ReferenceFolder.Open"); - public static readonly IBitmap ReferenceFolderClosed = LoadBitmap("ReferenceFolder.Closed"); + public static readonly Bitmap ReferenceFolderOpen = LoadBitmap("ReferenceFolder.Open"); + public static readonly Bitmap ReferenceFolderClosed = LoadBitmap("ReferenceFolder.Closed"); - public static readonly IBitmap SubTypes = LoadBitmap("SubTypes"); - public static readonly IBitmap SuperTypes = LoadBitmap("SuperTypes"); + public static readonly Bitmap SubTypes = LoadBitmap("SubTypes"); + public static readonly Bitmap SuperTypes = LoadBitmap("SuperTypes"); - public static readonly IBitmap FolderOpen = LoadBitmap("Folder.Open"); - public static readonly IBitmap FolderClosed = LoadBitmap("Folder.Closed"); + public static readonly Bitmap FolderOpen = LoadBitmap("Folder.Open"); + public static readonly Bitmap FolderClosed = LoadBitmap("Folder.Closed"); - public static readonly IBitmap Resource = LoadBitmap("Resource"); - public static readonly IBitmap ResourceImage = LoadBitmap("ResourceImage"); - public static readonly IBitmap ResourceResourcesFile = LoadBitmap("ResourceResourcesFile"); - public static readonly IBitmap ResourceXml = LoadBitmap("ResourceXml"); - public static readonly IBitmap ResourceXsd = LoadBitmap("ResourceXsd"); - public static readonly IBitmap ResourceXslt = LoadBitmap("ResourceXslt"); + public static readonly Bitmap Resource = LoadBitmap("Resource"); + public static readonly Bitmap ResourceImage = LoadBitmap("ResourceImage"); + public static readonly Bitmap ResourceResourcesFile = LoadBitmap("ResourceResourcesFile"); + public static readonly Bitmap ResourceXml = LoadBitmap("ResourceXml"); + public static readonly Bitmap ResourceXsd = LoadBitmap("ResourceXsd"); + public static readonly Bitmap ResourceXslt = LoadBitmap("ResourceXslt"); - public static readonly IBitmap Class = LoadBitmap("Class"); - public static readonly IBitmap Struct = LoadBitmap("Struct"); - public static readonly IBitmap Interface = LoadBitmap("Interface"); - public static readonly IBitmap Delegate = LoadBitmap("Delegate"); - public static readonly IBitmap Enum = LoadBitmap("Enum"); - public static readonly IBitmap StaticClass = LoadBitmap("StaticClass"); + public static readonly Bitmap Class = LoadBitmap("Class"); + public static readonly Bitmap Struct = LoadBitmap("Struct"); + public static readonly Bitmap Interface = LoadBitmap("Interface"); + public static readonly Bitmap Delegate = LoadBitmap("Delegate"); + public static readonly Bitmap Enum = LoadBitmap("Enum"); + public static readonly Bitmap StaticClass = LoadBitmap("StaticClass"); + public static readonly Bitmap Field = LoadBitmap("Field"); + public static readonly Bitmap FieldReadOnly = LoadBitmap("FieldReadOnly"); + public static readonly Bitmap Literal = LoadBitmap("Literal"); + public static readonly Bitmap EnumValue = LoadBitmap("EnumValue"); - public static readonly IBitmap Field = LoadBitmap("Field"); - public static readonly IBitmap FieldReadOnly = LoadBitmap("FieldReadOnly"); - public static readonly IBitmap Literal = LoadBitmap("Literal"); - public static readonly IBitmap EnumValue = LoadBitmap("EnumValue"); + public static readonly Bitmap Method = LoadBitmap("Method"); + public static readonly Bitmap Constructor = LoadBitmap("Constructor"); + public static readonly Bitmap VirtualMethod = LoadBitmap("VirtualMethod"); + public static readonly Bitmap Operator = LoadBitmap("Operator"); + public static readonly Bitmap ExtensionMethod = LoadBitmap("ExtensionMethod"); + public static readonly Bitmap PInvokeMethod = LoadBitmap("PInvokeMethod"); - public static readonly IBitmap Method = LoadBitmap("Method"); - public static readonly IBitmap Constructor = LoadBitmap("Constructor"); - public static readonly IBitmap VirtualMethod = LoadBitmap("VirtualMethod"); - public static readonly IBitmap Operator = LoadBitmap("Operator"); - public static readonly IBitmap ExtensionMethod = LoadBitmap("ExtensionMethod"); - public static readonly IBitmap PInvokeMethod = LoadBitmap("PInvokeMethod"); + public static readonly Bitmap Property = LoadBitmap("Property"); + public static readonly Bitmap Indexer = LoadBitmap("Indexer"); - public static readonly IBitmap Property = LoadBitmap("Property"); - public static readonly IBitmap Indexer = LoadBitmap("Indexer"); + public static readonly Bitmap Event = LoadBitmap("Event"); - public static readonly IBitmap Event = LoadBitmap("Event"); + private static readonly Bitmap OverlayProtected = LoadBitmap("OverlayProtected"); + private static readonly Bitmap OverlayInternal = LoadBitmap("OverlayInternal"); + private static readonly Bitmap OverlayProtectedInternal = LoadBitmap("OverlayProtectedInternal"); + private static readonly Bitmap OverlayPrivate = LoadBitmap("OverlayPrivate"); + private static readonly Bitmap OverlayPrivateProtected = LoadBitmap("OverlayPrivateProtected"); + private static readonly Bitmap OverlayCompilerControlled = LoadBitmap("OverlayCompilerControlled"); - private static readonly IBitmap OverlayProtected = LoadBitmap("OverlayProtected"); - private static readonly IBitmap OverlayInternal = LoadBitmap("OverlayInternal"); - private static readonly IBitmap OverlayProtectedInternal = LoadBitmap("OverlayProtectedInternal"); - private static readonly IBitmap OverlayPrivate = LoadBitmap("OverlayPrivate"); - private static readonly IBitmap OverlayPrivateProtected = LoadBitmap("OverlayPrivateProtected"); - private static readonly IBitmap OverlayCompilerControlled = LoadBitmap("OverlayCompilerControlled"); + private static readonly Bitmap OverlayStatic = LoadBitmap("OverlayStatic"); - private static readonly IBitmap OverlayStatic = LoadBitmap("OverlayStatic"); - - public static IBitmap LoadImage(object part, string icon) + public static Bitmap LoadImage(object part, string icon) { - IBitmap image; + Bitmap image; var assembly = part.GetType().Assembly; if (assembly == typeof(Images).Assembly) { image = new Bitmap(icon); @@ -112,20 +111,20 @@ public static IBitmap LoadImage(object part, string icon) var embededResourceStream = assembly.GetManifestResourceStream(icon); image = new Bitmap(embededResourceStream); } + return image; } - private static readonly TypeIconCache typeIconCache = new TypeIconCache(); private static readonly MemberIconCache memberIconCache = new MemberIconCache(); - public static IBitmap GetIcon(TypeIcon icon, AccessOverlayIcon overlay, bool isStatic = false) + public static Bitmap GetIcon(TypeIcon icon, AccessOverlayIcon overlay, bool isStatic = false) { lock (typeIconCache) return typeIconCache.GetIcon(icon, overlay, isStatic); } - public static IBitmap GetIcon(MemberIcon icon, AccessOverlayIcon overlay, bool isStatic) + public static Bitmap GetIcon(MemberIcon icon, AccessOverlayIcon overlay, bool isStatic) { lock (memberIconCache) return memberIconCache.GetIcon(icon, overlay, isStatic); @@ -145,9 +144,9 @@ public TypeIconCache() PreloadPublicIconToCache(TypeIcon.StaticClass, Images.StaticClass); } - protected override IBitmap GetBaseImage(TypeIcon icon) + protected override Bitmap GetBaseImage(TypeIcon icon) { - IBitmap baseImage; + Bitmap baseImage; switch (icon) { case TypeIcon.Class: baseImage = Images.Class; @@ -194,9 +193,9 @@ public MemberIconCache() PreloadPublicIconToCache(MemberIcon.Event, Images.Event); } - protected override IBitmap GetBaseImage(MemberIcon icon) + protected override Bitmap GetBaseImage(MemberIcon icon) { - IBitmap baseImage; + Bitmap baseImage; switch (icon) { case MemberIcon.Field: baseImage = Images.Field; @@ -250,7 +249,10 @@ private class WbFb : IFramebufferPlatformSurface WriteableBitmap _bitmap; public ILockedFramebuffer Lock() => _bitmap.Lock(); - public WbFb(WriteableBitmap bitmap) + // Avalonia v11 - https://github.com/AvaloniaUI/Avalonia/pull/11914 + public IFramebufferRenderTarget CreateFramebufferRenderTarget() => new FuncFramebufferRenderTarget(Lock); + + public WbFb(WriteableBitmap bitmap) { _bitmap = bitmap; } @@ -258,39 +260,39 @@ public WbFb(WriteableBitmap bitmap) private abstract class IconCache { - private readonly Dictionary, IBitmap> cache = new Dictionary, IBitmap>(); + private readonly Dictionary, Bitmap> cache = new Dictionary, Bitmap>(); - protected void PreloadPublicIconToCache(T icon, IBitmap image) + protected void PreloadPublicIconToCache(T icon, Bitmap image) { var iconKey = new Tuple(icon, AccessOverlayIcon.Public, false); cache.Add(iconKey, image); } - public IBitmap GetIcon(T icon, AccessOverlayIcon overlay, bool isStatic) + public Bitmap GetIcon(T icon, AccessOverlayIcon overlay, bool isStatic) { var iconKey = new Tuple(icon, overlay, isStatic); if (cache.ContainsKey(iconKey)) { return cache[iconKey]; } else { - IBitmap result = BuildMemberIcon(icon, overlay, isStatic); + Bitmap result = BuildMemberIcon(icon, overlay, isStatic); cache.Add(iconKey, result); return result; } } - private IBitmap BuildMemberIcon(T icon, AccessOverlayIcon overlay, bool isStatic) + private Bitmap BuildMemberIcon(T icon, AccessOverlayIcon overlay, bool isStatic) { - IBitmap baseImage = GetBaseImage(icon); - IBitmap overlayImage = GetOverlayImage(overlay); + Bitmap baseImage = GetBaseImage(icon); + Bitmap overlayImage = GetOverlayImage(overlay); return CreateOverlayImage(baseImage, overlayImage, isStatic); } - protected abstract IBitmap GetBaseImage(T icon); + protected abstract Bitmap GetBaseImage(T icon); - private static IBitmap GetOverlayImage(AccessOverlayIcon overlay) + private static Bitmap GetOverlayImage(AccessOverlayIcon overlay) { - IBitmap overlayImage; + Bitmap overlayImage; switch (overlay) { case AccessOverlayIcon.Public: overlayImage = null; @@ -321,11 +323,12 @@ private static IBitmap GetOverlayImage(AccessOverlayIcon overlay) private static readonly Rect iconRect = new Rect(0, 0, 16, 16); - private static IBitmap CreateOverlayImage(IBitmap baseImage, IBitmap overlay, bool isStatic) + private static Bitmap CreateOverlayImage(Bitmap baseImage, Bitmap overlay, bool isStatic) { var image = new WriteableBitmap(new PixelSize(16, 16), new Vector(96, 96), PixelFormat.Rgba8888, AlphaFormat.Unpremul); - using (var rt = AvaloniaLocator.Current.GetService().CreateRenderTarget(new[] { new WbFb(image)})) { + // Avalonia 0.10 - https://github.com/AvaloniaUI/Avalonia/pull/11557 + using (var rt = AvaloniaLocator.Current.GetService().CreateRenderTarget(new[] { new WbFb(image)})) { using (var ctx = rt.CreateDrawingContext(null)) { diff --git a/ILSpy.Core/Languages/CSharpLanguage.cs b/ILSpy.Core/Languages/CSharpLanguage.cs index 64f7366..fcb7ca6 100644 --- a/ILSpy.Core/Languages/CSharpLanguage.cs +++ b/ILSpy.Core/Languages/CSharpLanguage.cs @@ -350,7 +350,7 @@ void AddReferenceAssemblyWarningMessage(PEFile module, ITextOutput output) } void AddWarningMessage(PEFile module, ITextOutput output, string line1, string line2 = null, - string buttonText = null, IBitmap buttonImage = null, EventHandler buttonClickHandler = null) + string buttonText = null, Bitmap buttonImage = null, EventHandler buttonClickHandler = null) { if (output is ISmartTextOutput fancyOutput) { diff --git a/ILSpy.Core/MainWindow.xaml.cs b/ILSpy.Core/MainWindow.xaml.cs index 9103072..fcfbc62 100644 --- a/ILSpy.Core/MainWindow.xaml.cs +++ b/ILSpy.Core/MainWindow.xaml.cs @@ -40,11 +40,13 @@ using Avalonia.Markup.Xaml.Styling; using Avalonia.Media; using Avalonia.Media.Imaging; +using Avalonia.Platform; using Avalonia.Styling; using Avalonia.Threading; using AvaloniaEdit; using AvaloniaEdit.Highlighting; using AvaloniaEdit.Highlighting.Xshd; +using AvaloniaEdit.Utils; using ICSharpCode.Decompiler; using ICSharpCode.Decompiler.Documentation; using ICSharpCode.Decompiler.Metadata; @@ -82,7 +84,7 @@ public partial class MainWindow : PlatformDependentWindow, IRoutedCommandBindabl internal ItemsControl toolBar; internal ComboBox languageComboBox; internal ComboBox languageVersionComboBox; - internal IControl statusBar; + internal Control statusBar; internal TextBlock StatusLabel; internal Grid mainGrid; internal ColumnDefinition leftColumn; @@ -199,7 +201,7 @@ private void InitializeComponent() } var themesDropDown = this.Find("Themes"); - themesDropDown.Items = themeNames; + themesDropDown.ItemsSource = themeNames; themesDropDown.SelectionChanged += (sender, e) => { Styles[0] = themes[themesDropDown.SelectedIndex]; @@ -251,14 +253,17 @@ private void MainWindow_KeyDown(object sender, KeyEventArgs e) private void ApplyTheme() { - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && Styles.TryGetResource("ThemeBackgroundBrush", out object backgroundColor) && backgroundColor is ISolidColorBrush brush) + ThemeVariant defaultVariant = ThemeVariant.Default; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && Styles.TryGetResource("ThemeBackgroundBrush", defaultVariant, out object backgroundColor) && backgroundColor is ISolidColorBrush brush) { // HACK: SetTitleBarColor is a method in Avalonia.Native.WindowImpl var setTitleBarColorMethod = PlatformImpl.GetType().GetMethod("SetTitleBarColor"); setTitleBarColorMethod?.Invoke(PlatformImpl, new object[] { brush.Color }); } - if (Styles.TryGetResource("ILAsm-Mode", out object ilasm) && ilasm is string ilmode) + // Styles.TryGetResource(objKey, ThemeVariant, out objValue) + if (Styles.TryGetResource("ILAsm-Mode", defaultVariant, out object ilasm) && ilasm is string ilmode) { HighlightingManager.Instance.RegisterHighlighting( "ILAsm", new string[] { ".il" }, @@ -289,7 +294,7 @@ private void ApplyTheme() }); } - if (Styles.TryGetResource("CSharp-Mode", out object csharp) && csharp is string csmode) + if (Styles.TryGetResource("CSharp-Mode", defaultVariant, out object csharp) && csharp is string csmode) { HighlightingManager.Instance.RegisterHighlighting( "C#", new string[] { ".cs" }, @@ -327,7 +332,7 @@ private void ApplyTheme() void SetWindowBounds(Rect bounds) { ClientSize = bounds.Size; - Position = PixelPoint.FromPoint(bounds.Position, PlatformImpl.DesktopScaling); + Position = PixelPoint.FromPoint(bounds.Position, DesktopScaling); } #region Toolbar extensibility @@ -337,7 +342,7 @@ void InitToolbar() int navigationPos = 0; int openPos = 1; var toolbarCommands = App.ExportProvider.GetExports("ToolbarCommand"); - var toolbarItems = toolBar.Items as IList ?? new List(); + var toolbarItems = toolBar.ItemsSource as IList ?? new List(); foreach (var commandGroup in toolbarCommands.OrderBy(c => c.Metadata.ToolbarOrder).GroupBy(c => Properties.Resources.ResourceManager.GetString(c.Metadata.ToolbarCategory))) { if (commandGroup.Key == Properties.Resources.ResourceManager.GetString("Navigation")) { foreach (var command in commandGroup) { @@ -355,7 +360,8 @@ void InitToolbar() } } } - toolBar.Items = toolbarItems; + + toolBar.ItemsSource = toolbarItems; } Button MakeToolbarItem(Lazy command) @@ -370,6 +376,7 @@ Button MakeToolbarItem(Lazy command) Source = Images.LoadImage(command.Value, command.Metadata.ToolbarIcon) } }; + ToolTip.SetTip(toolbarButton, Properties.Resources.ResourceManager.GetString(command.Metadata.ToolTip)); return toolbarButton; } @@ -380,7 +387,7 @@ Button MakeToolbarItem(Lazy command) void InitMainMenu() { var mainMenuCommands = App.ExportProvider.GetExports("MainMenuCommand"); - var mainMenuItems = mainMenu.Items as IList ?? new List(); + var mainMenuItems = mainMenu.ItemsSource as IList ?? new List(); foreach (var topLevelMenu in mainMenuCommands.OrderBy(c => c.Metadata.MenuOrder).GroupBy(c => GetResourceString(c.Metadata.Menu))) { MenuItem topLevelMenuItem = mainMenu.Items.OfType().FirstOrDefault(m => (GetResourceString(m.Header as string)) == topLevelMenu.Key); var topLevelMenuItems = topLevelMenuItem?.Items as IList ?? new List(); @@ -392,6 +399,7 @@ void InitMainMenu() } else if (topLevelMenuItems.Count > 0) { topLevelMenuItems.Add(new Separator()); } + foreach (var entry in category) { MenuItem menuItem = new MenuItem(); menuItem.Command = CommandWrapper.Unwrap(entry.Value); @@ -409,9 +417,11 @@ void InitMainMenu() topLevelMenuItems.Add(menuItem); } } - topLevelMenuItem.Items = topLevelMenuItems; + + topLevelMenuItem.ItemsSource = topLevelMenuItems; } - mainMenu.Items = mainMenuItems; + + mainMenu.ItemsSource = mainMenuItems; } void InitNativeMenu() @@ -450,7 +460,8 @@ void InitNativeMenu() } } } - mainMenu.Items = mainMenuItems; + + mainMenu.ItemsSource = mainMenuItems; } internal static string GetResourceString(string key) @@ -474,7 +485,8 @@ static void OnShow(AvaloniaPropertyChangedEventArgs args) bool boundsOK = false; foreach (var screen in instance.Screens.All) { - var intersection = boundsRect.Intersect(screen.WorkingArea.ToRect(instance.PlatformImpl.DesktopScaling)); + // Avalonia v0.10 var intersection = boundsRect.Intersect(screen.WorkingArea.ToRect(instance.PlatformImpl.DesktopScaling)); + var intersection = boundsRect.Intersect(screen.WorkingArea.ToRect(instance.DesktopScaling)); if (intersection.Width > 10 && intersection.Height > 10) boundsOK = true; } @@ -671,7 +683,8 @@ private bool CanResolveTypeInPEFile(PEFile module, ITypeReference typeRef, out E void MainWindow_Loaded(object sender, EventArgs e) { - Application.Current.FocusManager.Focus(this); + var focusManager = TopLevel.GetTopLevel(this).FocusManager; + focusManager.GetFocusedElement().Focus(); InitToolbar(); @@ -1182,7 +1195,7 @@ async void LoadAssemblies(IEnumerable fileNames, List lo // Select only the last node to avoid multi selection if(lastNode != null) { treeView.SelectedItem = lastNode; - } + } } void RefreshCommandExecuted(object sender, ExecutedRoutedEventArgs e) @@ -1196,7 +1209,6 @@ void RefreshCommandExecuted(object sender, ExecutedRoutedEventArgs e) } finally { refreshInProgress = false; } - } void SearchCommandExecuted(object sender, ExecutedRoutedEventArgs e) @@ -1331,20 +1343,35 @@ void NavigateHistory(bool forward) #endregion - protected override void HandleWindowStateChanged(WindowState state) + // Avalonia v11 + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) { - base.HandleWindowStateChanged(state); - // store window state in settings only if it's not minimized - if (this.WindowState != WindowState.Minimized) - sessionSettings.WindowState = this.WindowState; + base.OnPropertyChanged(change); + + if (change.Property == WindowStateProperty) + { + // store window state in settings only if it's not minimized + if (this.WindowState != WindowState.Minimized) + sessionSettings.WindowState = this.WindowState; + } } - protected override bool HandleClosing() + // Avalonia v0.10 + ////protected override void HandleWindowStateChanged(WindowState state) + ////{ + //// base.HandleWindowStateChanged(state); + //// // store window state in settings only if it's not minimized + //// if (this.WindowState != WindowState.Minimized) + //// sessionSettings.WindowState = this.WindowState; + ////} + + protected override void OnClosing(WindowClosingEventArgs e) { sessionSettings.ActiveAssemblyList = assemblyList.ListName; sessionSettings.ActiveTreeViewPath = GetPathForNode(treeView.SelectedItem as SharpTreeNode); sessionSettings.ActiveAutoLoadedAssembly = GetAutoLoadedAssemblyNode(treeView.SelectedItem as SharpTreeNode); - sessionSettings.WindowBounds = new Rect(Position.ToPoint(PlatformImpl.DesktopScaling), ClientSize); + //// Avalonia v0.10: sessionSettings.WindowBounds = new Rect(Position.ToPoint(PlatformImpl.DesktopScaling), ClientSize); + sessionSettings.WindowBounds = new Rect(Position.ToPoint(DesktopScaling), ClientSize); sessionSettings.SplitterPosition = leftColumn.Width.Value / (leftColumn.Width.Value + rightColumn.Width.Value); if (topPane.IsVisible == true) sessionSettings.TopPaneSplitterPosition = topPaneRow.Height.Value / (topPaneRow.Height.Value + textViewRow.Height.Value); @@ -1352,8 +1379,25 @@ protected override bool HandleClosing() sessionSettings.BottomPaneSplitterPosition = bottomPaneRow.Height.Value / (bottomPaneRow.Height.Value + textViewRow.Height.Value); sessionSettings.Save(); - return base.HandleClosing(); - } + base.OnClosing(e); + } + + // Avalonia v0.10 + ////protected override bool HandleClosing() + ////{ + //// sessionSettings.ActiveAssemblyList = assemblyList.ListName; + //// sessionSettings.ActiveTreeViewPath = GetPathForNode(treeView.SelectedItem as SharpTreeNode); + //// sessionSettings.ActiveAutoLoadedAssembly = GetAutoLoadedAssemblyNode(treeView.SelectedItem as SharpTreeNode); + //// sessionSettings.WindowBounds = new Rect(Position.ToPoint(PlatformImpl.DesktopScaling), ClientSize); + //// sessionSettings.SplitterPosition = leftColumn.Width.Value / (leftColumn.Width.Value + rightColumn.Width.Value); + //// if (topPane.IsVisible == true) + //// sessionSettings.TopPaneSplitterPosition = topPaneRow.Height.Value / (topPaneRow.Height.Value + textViewRow.Height.Value); + //// if (bottomPane.IsVisible == true) + //// sessionSettings.BottomPaneSplitterPosition = bottomPaneRow.Height.Value / (bottomPaneRow.Height.Value + textViewRow.Height.Value); + //// sessionSettings.Save(); + //// + //// return base.HandleClosing(); + ////} private string GetAutoLoadedAssemblyNode(SharpTreeNode node) { @@ -1479,12 +1523,12 @@ public void SetStatus(string status, IBrush foreground) public IEnumerable GetMainMenuItems() { - return mainMenu.Items; + return mainMenu.ItemsSource; } public IEnumerable GetToolBarItems() { - return toolBar.Items; + return toolBar.ItemsSource; } } } diff --git a/ILSpy.Core/OpenListDialog.xaml.cs b/ILSpy.Core/OpenListDialog.xaml.cs index ab4c379..5407a8c 100644 --- a/ILSpy.Core/OpenListDialog.xaml.cs +++ b/ILSpy.Core/OpenListDialog.xaml.cs @@ -72,13 +72,14 @@ private void InitializeComponent() createButton.Click += CreateButton_Click; resetButton.Click += ResetButton_Click; - TemplateApplied += (sender, e) => Application.Current.FocusManager.Focus(listView); + TemplateApplied += (sender, e) => listView.Focus(); + listView.TemplateApplied += listView_Loaded; } private void listView_Loaded(object sender, EventArgs e) { - listView.Items = manager.AssemblyLists; + listView.ItemsSource = manager.AssemblyLists; CreateDefaultAssemblyLists(); } @@ -175,6 +176,5 @@ private void listView_MouseDoubleClick(object sender, RoutedEventArgs e) //this.DialogResult = true; this.Close(true); } - } } diff --git a/ILSpy.Core/Options/DisplaySettingsPanel.xaml.cs b/ILSpy.Core/Options/DisplaySettingsPanel.xaml.cs index 5540c78..e25048d 100644 --- a/ILSpy.Core/Options/DisplaySettingsPanel.xaml.cs +++ b/ILSpy.Core/Options/DisplaySettingsPanel.xaml.cs @@ -53,7 +53,7 @@ public DisplaySettingsPanel() Dispatcher.UIThread.InvokeAsync( (Action)( async () => { - fontSelector.Items = task.Result; + fontSelector.ItemsSource = task.Result; if (continuation.Exception != null) { foreach (var ex in continuation.Exception.InnerExceptions) { await MessageBox.Show(ex.ToString()); @@ -169,8 +169,7 @@ private void TextBox_PreviewTextInput(object sender, TextInputEventArgs e) } } - - public class FontSizeConverter : IValueConverter + public class FontSizeConverter : IValueConverter { public static readonly FontSizeConverter Instance = new FontSizeConverter(); @@ -206,4 +205,4 @@ public object ConvertBack(object value, Type targetType, object parameter, Syste throw new NotImplementedException(); } } -} \ No newline at end of file +} diff --git a/ILSpy.Core/Options/OptionsDialog.xaml.cs b/ILSpy.Core/Options/OptionsDialog.xaml.cs index 4daeae6..233f320 100644 --- a/ILSpy.Core/Options/OptionsDialog.xaml.cs +++ b/ILSpy.Core/Options/OptionsDialog.xaml.cs @@ -36,7 +36,7 @@ namespace ICSharpCode.ILSpy.Options public partial class OptionsDialog : DialogWindow { - readonly Lazy[] optionPages; + readonly Lazy[] optionPages; internal TabControl tabControl; @@ -50,7 +50,7 @@ public OptionsDialog() // ExportProvider instance. // FIXME: Ideally, the export provider should be disposed when it's no longer needed. var ep = App.ExportProviderFactory.CreateExportProvider(); - this.optionPages = ep.GetExports("OptionPages").ToArray(); + this.optionPages = ep.GetExports("OptionPages").ToArray(); ILSpySettings settings = ILSpySettings.Load(); var tabItems = new List(); foreach (var optionPage in optionPages.OrderBy(p => p.Metadata.Order)) { @@ -63,7 +63,8 @@ public OptionsDialog() if (page != null) page.Load(settings); } - tabControl.Items = tabItems; + + tabControl.ItemsSource = tabItems; } private void InitializeComponent() @@ -110,7 +111,7 @@ public interface IOptionPage [AttributeUsage(AttributeTargets.Class, AllowMultiple=false)] public class ExportOptionPageAttribute : ExportAttribute { - public ExportOptionPageAttribute() : base("OptionPages", typeof(IControl)) + public ExportOptionPageAttribute() : base("OptionPages", typeof(Control)) { } public string Title { get; set; } @@ -130,4 +131,4 @@ public override async void Execute(object parameter) } } } -} \ No newline at end of file +} diff --git a/ILSpy.Core/Search/AbstractSearchStrategy.cs b/ILSpy.Core/Search/AbstractSearchStrategy.cs index 716f9bb..92e9db6 100644 --- a/ILSpy.Core/Search/AbstractSearchStrategy.cs +++ b/ILSpy.Core/Search/AbstractSearchStrategy.cs @@ -227,7 +227,7 @@ string GetLanguageSpecificName(IEntity member) } } - IBitmap GetIcon(IEntity member) + Bitmap GetIcon(IEntity member) { switch (member) { diff --git a/ILSpy.Core/Search/SearchPane.xaml.cs b/ILSpy.Core/Search/SearchPane.xaml.cs index 55b476b..93eebcb 100644 --- a/ILSpy.Core/Search/SearchPane.xaml.cs +++ b/ILSpy.Core/Search/SearchPane.xaml.cs @@ -48,9 +48,9 @@ public partial class SearchPane : UserControl, IPane static SearchPane instance; RunningSearch currentSearch; bool runSearchOnNextShow; - DispatcherTimer updateResultTimer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(2D) }; + DispatcherTimer updateResultTimer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(2D) }; - public ObservableCollection Results { get; } = new ObservableCollection(); + public ObservableCollection Results { get; } = new ObservableCollection(); public static SearchPane Instance { get { @@ -66,32 +66,31 @@ public static SearchPane Instance { public SearchPane() { InitializeComponent(); - searchModeComboBox.Items = new []{ - new { Image = Images.Library, Name = "Types and Members" }, - new { Image = Images.Class, Name = "Type" }, - new { Image = Images.Property, Name = "Member" }, - new { Image = Images.Method, Name = "Method" }, - new { Image = Images.Field, Name = "Field" }, - new { Image = Images.Property, Name = "Property" }, - new { Image = Images.Event, Name = "Event" }, - new { Image = Images.Literal, Name = "Constant" }, - new { Image = Images.Library, Name = "Metadata Token" } - }; - + searchModeComboBox.ItemsSource = new []{ + new { Image = Images.Library, Name = "Types and Members" }, + new { Image = Images.Class, Name = "Type" }, + new { Image = Images.Property, Name = "Member" }, + new { Image = Images.Method, Name = "Method" }, + new { Image = Images.Field, Name = "Field" }, + new { Image = Images.Property, Name = "Property" }, + new { Image = Images.Event, Name = "Event" }, + new { Image = Images.Literal, Name = "Constant" }, + new { Image = Images.Library, Name = "Metadata Token" } + }; ContextMenuProvider.Add(listBox); MainWindow.Instance.CurrentAssemblyListChanged += MainWindow_Instance_CurrentAssemblyListChanged; MainWindow.Instance.SessionSettings.FilterSettings.PropertyChanged += FilterSettings_PropertyChanged; - // This starts empty search right away, so do at the end (we're still in ctor) - searchModeComboBox.SelectedIndex = (int)MainWindow.Instance.SessionSettings.SelectedSearchMode; + // This starts empty search right away, so do at the end (we're still in ctor) + searchModeComboBox.SelectedIndex = (int)MainWindow.Instance.SessionSettings.SelectedSearchMode; searchModeComboBox.SelectionChanged += (sender, e) => MainWindow.Instance.SessionSettings.SelectedSearchMode = (Search.SearchMode)searchModeComboBox.SelectedIndex; - updateResultTimer.Tick += UpdateResults; + updateResultTimer.Tick += UpdateResults; - this.DataContext = new DataGridCollectionView(Results); - } + this.DataContext = new DataGridCollectionView(Results); + } - void MainWindow_Instance_CurrentAssemblyListChanged(object sender, NotifyCollectionChangedEventArgs e) + void MainWindow_Instance_CurrentAssemblyListChanged(object sender, NotifyCollectionChangedEventArgs e) { if (VisualRoot != null) { StartSearch(this.SearchTerm); @@ -123,35 +122,37 @@ public void Show() StartSearch(this.SearchTerm); } } - Dispatcher.UIThread.InvokeAsync( - new Action( - delegate { - searchBox.Focus(); - //searchBox.SelectAll(); - searchBox.SelectionStart = 0; - searchBox.SelectionEnd = searchBox.Text?.Length ?? 0; - }), - DispatcherPriority.Background); - updateResultTimer.Start(); - } - - public static readonly StyledProperty SearchTermProperty = - AvaloniaProperty.Register("SearchTerm", string.Empty, notifying: OnSearchTermChanged); - - public string SearchTerm { + Dispatcher.UIThread.InvokeAsync( + new Action( + delegate { + searchBox.Focus(); + //searchBox.SelectAll(); + searchBox.SelectionStart = 0; + searchBox.SelectionEnd = searchBox.Text?.Length ?? 0; + }), + DispatcherPriority.Background); + updateResultTimer.Start(); + } + + public static readonly StyledProperty SearchTermProperty = + AvaloniaProperty.Register("SearchTerm", string.Empty); + + public string SearchTerm { get { return GetValue(SearchTermProperty) ?? string.Empty; } set { SetValue(SearchTermProperty, value ?? string.Empty); } } - static void OnSearchTermChanged(IAvaloniaObject o, bool changed) - { - if (changed) - { - ((SearchPane)o).StartSearch(o.GetValue(SearchTermProperty)); - } - } + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + if (change.Property == SearchTermProperty) + { + ((SearchPane)change.Sender).StartSearch(change.Sender.GetValue(SearchTermProperty)); + } + + base.OnPropertyChanged(change); + } - void SearchModeComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) + void SearchModeComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { MainWindow.Instance.SessionSettings.SelectedSearchMode = (SearchMode)searchModeComboBox.SelectedIndex; StartSearch(this.SearchTerm); @@ -160,8 +161,8 @@ void SearchModeComboBox_SelectionChanged(object sender, SelectionChangedEventArg void IPane.Closed() { this.SearchTerm = string.Empty; - updateResultTimer.Stop(); - } + updateResultTimer.Stop(); + } void ListBox_MouseDoubleClick(object sender, RoutedEventArgs e) { @@ -200,7 +201,7 @@ void SearchBox_PreviewKeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Down && Results.Count > 0) { e.Handled = true; - // TODO: movefocus + // TODO: movefocus //listBox.MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); listBox.SelectedIndex = 0; } @@ -298,46 +299,46 @@ public RunningSearch(LoadedAssembly[] assemblies, string searchTerm, SearchMode this.apiVisibility = apiVisibility; } - static IEnumerable Split(string str, Func controller) - { - int nextPiece = 0; - for (int c = 0; c < str.Length; c++) - { - if (controller(str[c])) - { - yield return str.Substring(nextPiece, c - nextPiece); - nextPiece = c + 1; - } - } - - yield return str.Substring(nextPiece); - } - - static string TrimMatchingQuotes(string input, char quote) - { - input = input.Trim(); - if (input.Length >= 2 && input[0] == quote && input[input.Length-1] == quote) - { - return input.Substring(1, input.Length - 2); - } - return input; - } - - string[] CommandLineToArgumentArray(string commandLine) - { - bool inQuotes = false; - - return Split(commandLine, c => - { - if (c == '\"') - { - inQuotes = !inQuotes; - } - return !inQuotes && c == ' '; - }).Select(arg => TrimMatchingQuotes(arg, '\"')) - .Where(arg => !string.IsNullOrEmpty(arg)) - .ToArray(); - } + static IEnumerable Split(string str, Func controller) + { + int nextPiece = 0; + for (int c = 0; c < str.Length; c++) + { + if (controller(str[c])) + { + yield return str.Substring(nextPiece, c - nextPiece); + nextPiece = c + 1; + } + } + + yield return str.Substring(nextPiece); + } + + static string TrimMatchingQuotes(string input, char quote) + { + input = input.Trim(); + if (input.Length >= 2 && input[0] == quote && input[input.Length-1] == quote) + { + return input.Substring(1, input.Length - 2); + } + return input; + } + + string[] CommandLineToArgumentArray(string commandLine) + { + bool inQuotes = false; + + return Split(commandLine, c => + { + if (c == '\"') + { + inQuotes = !inQuotes; + } + return !inQuotes && c == ' '; + }).Select(arg => TrimMatchingQuotes(arg, '\"')) + .Where(arg => !string.IsNullOrEmpty(arg)) + .ToArray(); + } public void Cancel() { @@ -427,21 +428,21 @@ AbstractSearchStrategy GetSearchStrategy() public sealed class SearchResult : IMemberTreeNode { public static readonly System.Collections.Generic.IComparer Comparer = new SearchResultComparer(); - + public IEntity Member { get; set; } public float Fitness { get; set; } - + public string Location { get; set; } public string Name { get; set; } public object ToolTip { get; set; } - public IBitmap Image { get; set; } - public IBitmap LocationImage { get; set; } - + public Bitmap Image { get; set; } + public Bitmap LocationImage { get; set; } + public override string ToString() { return Name; } - + class SearchResultComparer : System.Collections.Generic.IComparer { public int Compare(SearchResult x, SearchResult y) diff --git a/ILSpy.Core/TextView/AvaloniaEditTextOutput.cs b/ILSpy.Core/TextView/AvaloniaEditTextOutput.cs index 931783b..cd7c66e 100644 --- a/ILSpy.Core/TextView/AvaloniaEditTextOutput.cs +++ b/ILSpy.Core/TextView/AvaloniaEditTextOutput.cs @@ -98,7 +98,7 @@ public sealed class AvaloniaEditTextOutput : ISmartTextOutput internal bool EnableHyperlinks { get; set; } /// Embedded UIElements, see . - internal readonly List>> UIElements = new List>>(); + internal readonly List>> UIElements = new List>>(); public RichTextModel HighlightingModel { get; } = new RichTextModel(); @@ -298,12 +298,12 @@ public void MarkFoldEnd() this.Foldings.Add(f); } - public void AddUIElement(Func element) + public void AddUIElement(Func element) { if (element != null) { if (this.UIElements.Count > 0 && this.UIElements.Last().Key == this.TextLength) throw new InvalidOperationException("Only one UIElement is allowed for each position in the document"); - this.UIElements.Add(new KeyValuePair>(this.TextLength, new Lazy(element))); + this.UIElements.Add(new KeyValuePair>(this.TextLength, new Lazy(element))); } } diff --git a/ILSpy.Core/TextView/UIElementGenerator.cs b/ILSpy.Core/TextView/UIElementGenerator.cs index e309ea9..c1a9c0e 100644 --- a/ILSpy.Core/TextView/UIElementGenerator.cs +++ b/ILSpy.Core/TextView/UIElementGenerator.cs @@ -24,7 +24,7 @@ namespace ICSharpCode.ILSpy.TextView { - using Pair = KeyValuePair>; + using Pair = KeyValuePair>; /// /// Embeds UIElements in the text output. diff --git a/ILSpy.Core/TreeNodes/CopyFullyQualifiedNameContextMenuEntry.cs b/ILSpy.Core/TreeNodes/CopyFullyQualifiedNameContextMenuEntry.cs index b917cf9..b769734 100644 --- a/ILSpy.Core/TreeNodes/CopyFullyQualifiedNameContextMenuEntry.cs +++ b/ILSpy.Core/TreeNodes/CopyFullyQualifiedNameContextMenuEntry.cs @@ -1,8 +1,4 @@ -using System; -using System.Windows; -using ICSharpCode.Decompiler; -using ICSharpCode.Decompiler.Metadata; -using ICSharpCode.Decompiler.TypeSystem; +using Avalonia.Controls; using ICSharpCode.ILSpy.Properties; namespace ICSharpCode.ILSpy.TreeNodes @@ -20,8 +16,12 @@ public bool IsVisible(TextViewContext context) public void Execute(TextViewContext context) { var member = GetMemberNodeFromContext(context)?.Member; - if (member == null) return; - App.Current.Clipboard.SetTextAsync(member.ReflectionName); + if (member == null) + return; + + //// App.Current.Clipboard.SetTextAsync(member.ReflectionName); + var clipboard = App.Current.GetMainWindow()?.Clipboard; + clipboard.SetTextAsync(member.ReflectionName); } private IMemberTreeNode GetMemberNodeFromContext(TextViewContext context) diff --git a/ILSpy.Core/TreeNodes/EventTreeNode.cs b/ILSpy.Core/TreeNodes/EventTreeNode.cs index cb8e79c..0aa4886 100644 --- a/ILSpy.Core/TreeNodes/EventTreeNode.cs +++ b/ILSpy.Core/TreeNodes/EventTreeNode.cs @@ -53,7 +53,7 @@ public static object GetText(IEvent ev, Language language) public override object Icon => GetIcon(EventDefinition); - public static IBitmap GetIcon(IEvent @event) + public static Bitmap GetIcon(IEvent @event) { return Images.GetIcon(MemberIcon.Event, MethodTreeNode.GetOverlayIcon(@event.Accessibility), @event.IsStatic); } diff --git a/ILSpy.Core/TreeNodes/FieldTreeNode.cs b/ILSpy.Core/TreeNodes/FieldTreeNode.cs index ee80ea8..1873e2d 100644 --- a/ILSpy.Core/TreeNodes/FieldTreeNode.cs +++ b/ILSpy.Core/TreeNodes/FieldTreeNode.cs @@ -45,7 +45,7 @@ public static object GetText(IField field, Language language) public override object Icon => GetIcon(FieldDefinition); - public static IBitmap GetIcon(IField field) + public static Bitmap GetIcon(IField field) { if (field.DeclaringType.Kind == TypeKind.Enum && field.ReturnType.Kind == TypeKind.Enum) return Images.GetIcon(MemberIcon.EnumValue, MethodTreeNode.GetOverlayIcon(field.Accessibility), false); diff --git a/ILSpy.Core/TreeNodes/MethodTreeNode.cs b/ILSpy.Core/TreeNodes/MethodTreeNode.cs index bd0e12d..25222a8 100644 --- a/ILSpy.Core/TreeNodes/MethodTreeNode.cs +++ b/ILSpy.Core/TreeNodes/MethodTreeNode.cs @@ -45,7 +45,7 @@ public static object GetText(IMethod method, Language language) public override object Icon => GetIcon(MethodDefinition); - public static IBitmap GetIcon(IMethod method) + public static Bitmap GetIcon(IMethod method) { if (method.IsOperator) return Images.GetIcon(MemberIcon.Operator, GetOverlayIcon(method.Accessibility), false); diff --git a/ILSpy.Core/TreeNodes/PropertyTreeNode.cs b/ILSpy.Core/TreeNodes/PropertyTreeNode.cs index 286ade6..0631ca8 100644 --- a/ILSpy.Core/TreeNodes/PropertyTreeNode.cs +++ b/ILSpy.Core/TreeNodes/PropertyTreeNode.cs @@ -59,7 +59,7 @@ public static object GetText(IProperty property, Language language) public override object Icon => GetIcon(PropertyDefinition); - public static IBitmap GetIcon(IProperty property) + public static Bitmap GetIcon(IProperty property) { return Images.GetIcon(property.IsIndexer ? MemberIcon.Indexer : MemberIcon.Property, MethodTreeNode.GetOverlayIcon(property.Accessibility), property.IsStatic); diff --git a/ILSpy.Core/TreeNodes/ResourceNodes/IconResourceEntryNode.cs b/ILSpy.Core/TreeNodes/ResourceNodes/IconResourceEntryNode.cs index ec332ec..1ded724 100644 --- a/ILSpy.Core/TreeNodes/ResourceNodes/IconResourceEntryNode.cs +++ b/ILSpy.Core/TreeNodes/ResourceNodes/IconResourceEntryNode.cs @@ -86,9 +86,9 @@ namespace ICSharpCode.ILSpy.TreeNodes // } // } - // private static void AddIcon(AvaloniaEditTextOutput output, IBitmap frame) + // private static void AddIcon(AvaloniaEditTextOutput output, Bitmap frame) // { // output.AddUIElement(() => new Image { Source = frame }); // } //} -} \ No newline at end of file +} diff --git a/ILSpy.Core/TreeNodes/ResourceNodes/ImageResourceEntryNode.cs b/ILSpy.Core/TreeNodes/ResourceNodes/ImageResourceEntryNode.cs index a2129f1..af487ed 100644 --- a/ILSpy.Core/TreeNodes/ResourceNodes/ImageResourceEntryNode.cs +++ b/ILSpy.Core/TreeNodes/ResourceNodes/ImageResourceEntryNode.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -69,7 +69,7 @@ public override bool View(DecompilerTextView textView) try { AvaloniaEditTextOutput output = new AvaloniaEditTextOutput(); Data.Position = 0; - IBitmap image = new Bitmap(Data); + Bitmap image = new Bitmap(Data); output.AddUIElement(() => new Image { Source = image }); output.WriteLine(); output.AddButton(Images.Save, Resources.Save, async delegate { diff --git a/ILSpy.Core/TreeNodes/ThreadingSupport.cs b/ILSpy.Core/TreeNodes/ThreadingSupport.cs index 246676c..39295d7 100644 --- a/ILSpy.Core/TreeNodes/ThreadingSupport.cs +++ b/ILSpy.Core/TreeNodes/ThreadingSupport.cs @@ -22,10 +22,8 @@ using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Windows; using Avalonia.Threading; using ICSharpCode.Decompiler; -using ICSharpCode.ILSpy.Analyzers; using ICSharpCode.ILSpy.Properties; using ICSharpCode.TreeView; @@ -79,8 +77,10 @@ public void LoadChildren(SharpTreeNode node, Func GetIcon(TypeDefinition); - public static IBitmap GetIcon(ITypeDefinition type) + public static Bitmap GetIcon(ITypeDefinition type) { return Images.GetIcon(GetTypeIcon(type), GetOverlayIcon(type)); } diff --git a/ILSpy.sln b/ILSpy.sln index 8b46fcd..4ffedae 100644 --- a/ILSpy.sln +++ b/ILSpy.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27130.2026 +# Visual Studio Version 17 +VisualStudioVersion = 17.6.33829.357 MinimumVisualStudioVersion = 15.0 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "doc", "doc", "{F45DB999-7E72-4000-B5AD-3A7B485A0896}" ProjectSection(SolutionItems) = preProject @@ -20,6 +20,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILSpy", "ILSpy\ILSpy.csproj EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ICSharpCode.Decompiler.PdbProvider.Cecil", "ICSharpCode.Decompiler.PdbProvider.Cecil\ICSharpCode.Decompiler.PdbProvider.Cecil.csproj", "{1B68749F-8434-4788-B5E5-781A1AF75595}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F778869B-877D-49C6-AD94-EFA11CD050B1}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + Directory.Build.props = Directory.Build.props + Directory.Build.targets = Directory.Build.targets + README.md = README.md + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -34,10 +42,6 @@ Global {7BB39313-8FC6-40A4-A06F-FD2A10817256}.Debug|Any CPU.Build.0 = Debug|Any CPU {7BB39313-8FC6-40A4-A06F-FD2A10817256}.Release|Any CPU.ActiveCfg = Release|Any CPU {7BB39313-8FC6-40A4-A06F-FD2A10817256}.Release|Any CPU.Build.0 = Release|Any CPU - {CC3151F6-C080-4E17-9F50-58C3FED64F28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CC3151F6-C080-4E17-9F50-58C3FED64F28}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CC3151F6-C080-4E17-9F50-58C3FED64F28}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CC3151F6-C080-4E17-9F50-58C3FED64F28}.Release|Any CPU.Build.0 = Release|Any CPU {5C561A81-4427-418A-B773-3840D2B32C4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5C561A81-4427-418A-B773-3840D2B32C4D}.Debug|Any CPU.Build.0 = Debug|Any CPU {5C561A81-4427-418A-B773-3840D2B32C4D}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/ILSpy/Program.cs b/ILSpy/Program.cs index 75ee634..1ee0928 100644 --- a/ILSpy/Program.cs +++ b/ILSpy/Program.cs @@ -29,7 +29,6 @@ static void Main(string[] args) } } - /// /// This method is needed for IDE previewer infrastructure /// @@ -37,7 +36,6 @@ public static AppBuilder BuildAvaloniaApp() { var result = AppBuilder.Configure(); - #if DEBUG result.LogToTrace(); Logger.Sink = new ProxyLogSink(Logger.Sink); @@ -89,23 +87,27 @@ public void Log(LogEventLevel level, string area, object source, string messageT { propertyValues[i] = GetHierachy(propertyValues[i]); } + sink.Log(level, area, source, messageTemplate, propertyValues); } object GetHierachy(object source) { - if (source is IControl visual) + if (source is Control visual) { List hierachy = new List(); hierachy.Add(visual.ToString()); + ////while ((visual = visual.Parent) != null) while ((visual = visual.Parent) != null) { hierachy.Insert(0, visual.ToString()); } + return string.Join("/", hierachy); } + return source; } } } -} \ No newline at end of file +} diff --git a/SharpTreeView/ExtensionMethods.cs b/SharpTreeView/ExtensionMethods.cs index 657e73a..d59dc8b 100644 --- a/SharpTreeView/ExtensionMethods.cs +++ b/SharpTreeView/ExtensionMethods.cs @@ -12,7 +12,7 @@ namespace ICSharpCode.TreeView { static class ExtensionMethods { - public static T FindAncestor(this IVisual d) where T : class + public static T FindAncestor(this Visual d) where T : class { return d.GetVisualAncestors().OfType().FirstOrDefault(); } diff --git a/SharpTreeView/SharpTreeNodeView.cs b/SharpTreeView/SharpTreeNodeView.cs index e613756..a5df0bd 100644 --- a/SharpTreeView/SharpTreeNodeView.cs +++ b/SharpTreeView/SharpTreeNodeView.cs @@ -32,6 +32,7 @@ public IBrush TextBackground if (!expanded.HasValue) { return null; } + return expanded.Value ? owner.Node?.ExpandedIcon : owner.Node?.Icon; }); @@ -40,7 +41,6 @@ public object Icon get { return GetValue(IconProperty); } } - public SharpTreeNode Node { get { return DataContext as SharpTreeNode; } @@ -97,14 +97,18 @@ protected override void OnApplyTemplate(TemplateAppliedEventArgs e) UpdateTemplate(); } - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e) + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) { - base.OnPropertyChanged(e); - if (e.Property == DataContextProperty) - { - UpdateDataContext(e.OldValue.GetValueOrDefault(), e.NewValue.GetValueOrDefault()); - } - } + base.OnPropertyChanged(change); + if (change.Property == DataContextProperty) + { + var e = (AvaloniaPropertyChangedEventArgs)change; + var oldTransitions = e.OldValue.GetValueOrDefault(); + var newTransitions = e.NewValue.GetValueOrDefault(); + + UpdateDataContext(oldTransitions, newTransitions); + } + } void UpdateDataContext(SharpTreeNode oldNode, SharpTreeNode newNode) { diff --git a/SharpTreeView/SharpTreeView.cs b/SharpTreeView/SharpTreeView.cs index 723da52..3cc3e07 100644 --- a/SharpTreeView/SharpTreeView.cs +++ b/SharpTreeView/SharpTreeView.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Collections.Specialized; +using System.ComponentModel; using System.Diagnostics; using System.Linq; using Avalonia; @@ -110,7 +111,7 @@ public static void SetShowAlternation(AvaloniaObject obj, bool value) Type IStyleable.StyleKey => typeof(ListBox); - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e) + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e) { base.OnPropertyChanged(e); if (e.Property == RootProperty || @@ -155,7 +156,7 @@ void Reload() } flattener = new TreeFlattener(Root, ShowRoot); flattener.CollectionChanged += flattener_CollectionChanged; - this.Items = flattener; + this.ItemsSource = flattener; } } @@ -191,46 +192,89 @@ void UpdateFocusedNode(List newSelection, int topSelectedIndex) } } - protected override IItemContainerGenerator CreateItemContainerGenerator() - { - return new ItemContainerGenerator( - this, - SharpTreeViewItem.ContentProperty, - SharpTreeViewItem.ContentTemplateProperty); - } - - protected override void OnContainersMaterialized(ItemContainerEventArgs e) - { - base.OnContainersMaterialized(e); - foreach (var item in e.Containers) { - var container = item.ContainerControl as SharpTreeViewItem; - container.ParentTreeView = this; - // Make sure that the line renderer takes into account the new bound data - if (container.NodeView != null) { - container.NodeView.LinesRenderer.InvalidateVisual(); - } - } - } + // Avalonia v11 - Removing, not being referenced.. Should we use, CreateContainerForItemOverride()? + ////[Obsolete("Marked for removal in Avalonia v12")] + ////protected override IItemContainerGenerator CreateItemContainerGenerator() + ////{ + //// return new ItemContainerGenerator( + //// this, + //// SharpTreeViewItem.ContentProperty, + //// SharpTreeViewItem.ContentTemplateProperty); + ////} - protected override void OnContainersRecycled(ItemContainerEventArgs e) + // NEW: Avalonia 11 (testing replacement for OnContainersMaterialized) + protected override void PrepareContainerForItemOverride(Control container, object item, int index) { - base.OnContainersRecycled(e); + base.PrepareContainerForItemOverride(container, item, index); - foreach (var item in e.Containers) + // TODO: See PR 9677 + var tvi = container as SharpTreeViewItem; + tvi.ParentTreeView = this; + if (tvi.NodeView != null) { - var container = item.ContainerControl as SharpTreeViewItem; - container.ParentTreeView = this; - // Make sure that the line renderer takes into account the new bound data - if (container.NodeView != null) - { - container.NodeView.LinesRenderer.InvalidateVisual(); - } - } - } - - internal IControl ContainerFromItem(object item) - { - int index = IndexOf(Items, item); + tvi.NodeView.LinesRenderer.InvalidateVisual(); + } + } + + // Avalonia v0.10 (PR 9677 - https://github.com/AvaloniaUI/Avalonia/pull/9677) + ////protected override void OnContainersMaterialized(ItemContainerEventArgs e) + ////{ + //// base.OnContainersMaterialized(e); + //// foreach (var item in e.Containers) { + //// var container = item.ContainerControl as SharpTreeViewItem; + //// container.ParentTreeView = this; + //// // Make sure that the line renderer takes into account the new bound data + //// if (container.NodeView != null) { + //// container.NodeView.LinesRenderer.InvalidateVisual(); + //// } + //// } + ////} + + // NEW: Avalonia 11 (testing replacement for OnContainersRecycled) + protected override void ClearContainerForItemOverride(Control element) + { + base.ClearContainerForItemOverride(element); + var tvi = element as SharpTreeViewItem; + tvi.ParentTreeView = this; + if (tvi.NodeView != null) + { + tvi.NodeView.LinesRenderer.InvalidateVisual(); + } + } + + // NEW: Avalonia 11 (testing replacement for OnContainersRecycled) + protected override void ContainerIndexChangedOverride(Control container, int oldIndex, int newIndex) + { + base.ContainerIndexChangedOverride(container, oldIndex, newIndex); + ////var tvi = container as SharpTreeViewItem; + ////tvi.ParentTreeView = this; + ////if (tvi.NodeView != null) + ////{ + //// tvi.NodeView.LinesRenderer.InvalidateVisual(); + ////} + } + + // OLD: Avalonia v0.10 + ////protected override void OnContainersRecycled(ItemContainerEventArgs e) + ////{ + //// base.OnContainersRecycled(e); + //// + //// foreach (var item in e.Containers) + //// { + //// var container = item.ContainerControl as SharpTreeViewItem; + //// container.ParentTreeView = this; + //// // Make sure that the line renderer takes into account the new bound data + //// if (container.NodeView != null) + //// { + //// container.NodeView.LinesRenderer.InvalidateVisual(); + //// } + //// } + ////} + + internal Control ContainerFromItem(object item) + { + int index = ItemsView.IndexOf(item); // Avalonia v11 + //// int index = IndexOf(Items, item); // Avalonia v0.10 if (index != -1) { return ItemContainerGenerator.ContainerFromIndex(index); } @@ -274,7 +318,7 @@ protected override void OnKeyDown(KeyEventArgs e) SharpTreeViewItem container = e.Source as SharpTreeViewItem; switch (e.Key) { case Key.Left: - if (container != null && ItemContainerGenerator.IndexFromContainer(e.Source as IControl) != -1) { + if (container != null && ItemContainerGenerator.IndexFromContainer(e.Source as Control) != -1) { if (container.Node.IsExpanded) { container.Node.IsExpanded = false; } else if (container.Node.Parent != null) { @@ -285,7 +329,7 @@ protected override void OnKeyDown(KeyEventArgs e) break; case Key.Right: // TODO: focus on first child - if (container != null && ItemContainerGenerator.IndexFromContainer(e.Source as IControl) != -1) { + if (container != null && ItemContainerGenerator.IndexFromContainer(e.Source as Control) != -1) { if (!container.Node.IsExpanded && container.Node.ShowExpander) { container.Node.IsExpanded = true; } else if (container.Node.Children.Count > 0) { @@ -303,19 +347,19 @@ protected override void OnKeyDown(KeyEventArgs e) } break; case Key.Add: - if (container != null && ItemContainerGenerator.IndexFromContainer(e.Source as IControl) != -1) { + if (container != null && ItemContainerGenerator.IndexFromContainer(e.Source as Control) != -1) { container.Node.IsExpanded = true; e.Handled = true; } break; case Key.Subtract: - if (container != null && ItemContainerGenerator.IndexFromContainer(e.Source as IControl) != -1) { + if (container != null && ItemContainerGenerator.IndexFromContainer(e.Source as Control) != -1) { container.Node.IsExpanded = false; e.Handled = true; } break; case Key.Multiply: - if (container != null && ItemContainerGenerator.IndexFromContainer(e.Source as IControl) != -1) { + if (container != null && ItemContainerGenerator.IndexFromContainer(e.Source as Control) != -1) { container.Node.IsExpanded = true; ExpandRecursively(container.Node); e.Handled = true; @@ -348,7 +392,7 @@ protected override void OnKeyDown(KeyEventArgs e) protected override void OnTextInput(TextInputEventArgs e) { - if (!string.IsNullOrEmpty(e.Text) && IsTextSearchEnabled && (e.Source == this || ItemContainerGenerator.IndexFromContainer(e.Source as IControl) != -1)) { + if (!string.IsNullOrEmpty(e.Text) && IsTextSearchEnabled && (e.Source == this || ItemContainerGenerator.IndexFromContainer(e.Source as Control) != -1)) { var instance = SharpTreeViewTextSearch.GetInstance(this); if (instance != null) { instance.Search(e.Text); diff --git a/SharpTreeView/SharpTreeViewTextSearch.cs b/SharpTreeView/SharpTreeViewTextSearch.cs index 108859a..9d85e1d 100644 --- a/SharpTreeView/SharpTreeViewTextSearch.cs +++ b/SharpTreeView/SharpTreeViewTextSearch.cs @@ -62,7 +62,7 @@ public bool RevertLastCharacter() public bool Search(string nextChar) { - IList items = (IList)treeView.Items; + IList items = (IList)treeView.ItemsSource; int startIndex = isActive ? lastMatchIndex : Math.Max(0, treeView.SelectedIndex); bool lookBackwards = inputStack.Count > 0 && string.Compare(inputStack.Peek(), nextChar, StringComparison.OrdinalIgnoreCase) == 0; int nextMatchIndex = IndexOfMatch(matchPrefix + nextChar, startIndex, lookBackwards, out bool wasNewCharUsed); @@ -86,7 +86,7 @@ public bool Search(string nextChar) int IndexOfMatch(string needle, int startIndex, bool tryBackward, out bool charWasUsed) { - IList items = (IList)treeView.Items; + IList items = (IList)treeView.ItemsSource; charWasUsed = false; if (items.Count == 0 || string.IsNullOrEmpty(needle)) return -1; @@ -143,4 +143,4 @@ void ResetTimeout() timer.Start(); } } -} \ No newline at end of file +}