提交 36c5fe05 编写于 作者: B Balaji Krishnan

Bring other options onboard ..

.. the new CodeStyle options UI page.

Notes:
1. UseVarForDeclarations - the option used by some features isn't
onboard, it is to be replaced by the new use var options.

2. Since the existing options are part of public api, we keep the
options' data structure as such and map the type to a corresponding view
which is used to update the UI. Since they were all underlying boolean
options, we introduce a BooleanCodeStyleOptionViewModel that maps to a
CodeStyleOption type and back.

3. update the StyleViewModel to create options using these new view
models.
上级 26d68cba
......@@ -619,7 +619,7 @@ internal class CSharpVSResources {
}
/// <summary>
/// Looks up a localized string similar to Prefer intrinsic predefined type keyword when declaring locals, parameters and members.
/// Looks up a localized string similar to For locals, parameters and members.
/// </summary>
internal static string PreferIntrinsicPredefinedTypeKeywordInDeclaration {
get {
......@@ -628,7 +628,7 @@ internal class CSharpVSResources {
}
/// <summary>
/// Looks up a localized string similar to Prefer intrinsic predefined type keyword in member access expressions.
/// Looks up a localized string similar to For member access expressions.
/// </summary>
internal static string PreferIntrinsicPredefinedTypeKeywordInMemberAccess {
get {
......
......@@ -313,10 +313,10 @@
<value>Use 'var' when generating locals</value>
</data>
<data name="PreferIntrinsicPredefinedTypeKeywordInDeclaration" xml:space="preserve">
<value>Prefer intrinsic predefined type keyword when declaring locals, parameters and members</value>
<value>For locals, parameters and members</value>
</data>
<data name="PreferIntrinsicPredefinedTypeKeywordInMemberAccess" xml:space="preserve">
<value>Prefer intrinsic predefined type keyword in member access expressions</value>
<value>For member access expressions</value>
</data>
<data name="Option_AllowMovingDeclaration" xml:space="preserve">
<value>_Move local declaration to the extracted method if it is not used elsewhere</value>
......
......@@ -17,13 +17,15 @@ namespace Microsoft.VisualStudio.LanguageServices.CSharp.Options.Formatting
// Must work with GridOptionPreviewControl
internal class StyleViewModel : AbstractOptionPreviewViewModel
{
public ObservableCollection<SimpleCodeStyleOptionViewModel> CodeStyleItems { get; set; }
public ObservableCollection<AbstractCodeStyleOptionViewModel> CodeStyleItems { get; set; }
internal override bool ShouldPersistOption(OptionKey key)
{
return key.Option.Feature == CSharpCodeStyleOptions.FeatureName || key.Option.Feature == SimplificationOptions.PerLanguageFeatureName;
}
#region "Preview Text"
private static readonly string s_declarationPreviewTrue = @"
class C{
int x;
......@@ -179,89 +181,47 @@ void foo()
//]
}
}";
#endregion
internal StyleViewModel(OptionSet optionSet, IServiceProvider serviceProvider) : base(optionSet, serviceProvider, LanguageNames.CSharp)
{
CodeStyleItems = new ObservableCollection<AbstractCodeStyleOptionViewModel>();
ListCollectionView collectionView = (ListCollectionView)CollectionViewSource.GetDefaultView(CodeStyleItems);
collectionView.GroupDescriptions.Add(new PropertyGroupDescription(nameof(AbstractCodeStyleOptionViewModel.GroupName)));
CodeStyleItems = new ObservableCollection<SimpleCodeStyleOptionViewModel>();
// TODO: move all strings from here to resx for loc.
ListCollectionView collectionView = (ListCollectionView)CollectionViewSource.GetDefaultView(CodeStyleItems);
collectionView.GroupDescriptions.Add(new PropertyGroupDescription(nameof(SimpleCodeStyleOptionViewModel.GroupName)));
const string qualifyGroupTitle = "this. preferences:";
const string predefinedTypesGroupTitle = "predefined type preferences:";
const string varGroupTitle = "'var' preferences:";
//this works:
//CodeStyleItems.Add(new SimpleCodeStyleOptionViewModel(SimplificationOptions.QualifyMemberAccessWithThisOrMe, CSharpVSResources.QualifyMemberAccessWithThis, s_declarationPreviewTrue, s_declarationPreviewFalse, this, optionSet));
//CodeStyleItems.Add(new SimpleCodeStyleOptionViewModel(SimplificationOptions.PreferIntrinsicPredefinedTypeKeywordInDeclaration, CSharpVSResources.PreferIntrinsicPredefinedTypeKeywordInDeclaration, s_intrinsicPreviewDeclarationTrue, s_intrinsicPreviewDeclarationFalse, this, optionSet));
//CodeStyleItems.Add(new SimpleCodeStyleOptionViewModel(SimplificationOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess, CSharpVSResources.PreferIntrinsicPredefinedTypeKeywordInMemberAccess, s_intrinsicPreviewMemberAccessTrue, s_intrinsicPreviewMemberAccessFalse, this, optionSet));
//CodeStyleItems.Add(SimpleCodeStyleOptionViewModel.Header("'var' preferences"));
var qualifyMemberAccessPreferences = new List<CodeStylePreference>
{
new CodeStylePreference("Prefer this.", true),
new CodeStylePreference("Do not prefer this.", false),
};
var predefinedTypesPreferences = new List<CodeStylePreference>
{
new CodeStylePreference("Prefer predefined type", true),
new CodeStylePreference("Prefer framework type", false),
};
var useVarPreferences = new List<CodeStylePreference>
{
// TODO: move to resx for loc.
new CodeStylePreference("Prefer 'var'", true),
new CodeStylePreference("Prefer explicit type", false),
};
const string varGroupTitle = "'var' preferences:";
CodeStyleItems.Add(new BooleanCodeStyleOptionViewModel(SimplificationOptions.QualifyMemberAccessWithThisOrMe, CSharpVSResources.QualifyMemberAccessWithThis, s_declarationPreviewTrue, s_declarationPreviewFalse, this, optionSet, qualifyGroupTitle, qualifyMemberAccessPreferences));
CodeStyleItems.Add(new BooleanCodeStyleOptionViewModel(SimplificationOptions.PreferIntrinsicPredefinedTypeKeywordInDeclaration, CSharpVSResources.PreferIntrinsicPredefinedTypeKeywordInDeclaration, s_intrinsicPreviewDeclarationTrue, s_intrinsicPreviewDeclarationFalse, this, optionSet, predefinedTypesGroupTitle, predefinedTypesPreferences));
CodeStyleItems.Add(new BooleanCodeStyleOptionViewModel(SimplificationOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess, CSharpVSResources.PreferIntrinsicPredefinedTypeKeywordInMemberAccess, s_intrinsicPreviewMemberAccessTrue, s_intrinsicPreviewMemberAccessFalse, this, optionSet, predefinedTypesGroupTitle, predefinedTypesPreferences));
CodeStyleItems.Add(new SimpleCodeStyleOptionViewModel(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes, CSharpVSResources.UseVarForIntrinsicTypes, s_varForIntrinsicsPreviewTrue, s_varForIntrinsicsPreviewFalse, this, optionSet, varGroupTitle, useVarPreferences));
CodeStyleItems.Add(new SimpleCodeStyleOptionViewModel(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, CSharpVSResources.UseVarWhenTypeIsApparent, s_varWhereApparentPreviewTrue, s_varWhereApparentPreviewFalse, this, optionSet, varGroupTitle, useVarPreferences));
CodeStyleItems.Add(new SimpleCodeStyleOptionViewModel(CSharpCodeStyleOptions.UseImplicitTypeWherePossible, CSharpVSResources.UseVarWhenPossible, s_varWherePossiblePreviewTrue, s_varWherePossiblePreviewFalse, this, optionSet, varGroupTitle, useVarPreferences));
//trying this:
//CodeStyleItems.Add(new StyleOptionViewModel(new CodeStyleItem(CSharpVSResources.UseVarForIntrinsicTypes, defaultPreferences)));
//CodeStyleItems.Add(new StyleOptionViewModel(new CodeStyleItem(CSharpVSResources.UseVarWhenTypeIsApparent, defaultPreferences)));
//CodeStyleItems.Add(new StyleOptionViewModel(new CodeStyleItem(CSharpVSResources.UseVarWhenPossible, defaultPreferences)));
// badness ensues when i store it in Items. hrmm..
// Old code:
//Items.Add(new CheckBoxOptionViewModel(SimplificationOptions.QualifyMemberAccessWithThisOrMe, CSharpVSResources.QualifyMemberAccessWithThis, s_declarationPreviewTrue, s_declarationPreviewFalse, this, optionSet));
//Items.Add(new CheckBoxOptionViewModel(SimplificationOptions.PreferIntrinsicPredefinedTypeKeywordInDeclaration, CSharpVSResources.PreferIntrinsicPredefinedTypeKeywordInDeclaration, s_intrinsicPreviewDeclarationTrue, s_intrinsicPreviewDeclarationFalse, this, optionSet));
//Items.Add(new CheckBoxOptionViewModel(SimplificationOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess, CSharpVSResources.PreferIntrinsicPredefinedTypeKeywordInMemberAccess, s_intrinsicPreviewMemberAccessTrue, s_intrinsicPreviewMemberAccessFalse, this, optionSet));
//Items.Add(new CheckBoxOptionViewModel(CSharpCodeStyleOptions.UseVarWhenDeclaringLocals, CSharpVSResources.UseVarWhenGeneratingLocals, s_varPreviewTrue, s_varPreviewFalse, this, optionSet));
//Items.Add(new HeaderItemViewModel() { Header = CSharpVSResources.SetTypeInferencePreferences });
//var notificationOptions = new List<NotificationOptionViewModel>
// {
// new NotificationOptionViewModel(NotificationOption.None, KnownMonikers.None),
// new NotificationOptionViewModel(NotificationOption.Info, KnownMonikers.StatusInformation),
// new NotificationOptionViewModel(NotificationOption.Warning, KnownMonikers.StatusWarning),
// new NotificationOptionViewModel(NotificationOption.Error, KnownMonikers.StatusError)
// };
//Items.Add(new CheckBoxWithComboOptionViewModel(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes, CSharpVSResources.UseVarForIntrinsicTypes, s_varForIntrinsicsPreviewTrue, s_varForIntrinsicsPreviewFalse, this, optionSet, notificationOptions));
//Items.Add(new CheckBoxWithComboOptionViewModel(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, CSharpVSResources.UseVarWhenTypeIsApparent, s_varWhereApparentPreviewTrue, s_varWhereApparentPreviewFalse, this, optionSet, notificationOptions));
//Items.Add(new CheckBoxWithComboOptionViewModel(CSharpCodeStyleOptions.UseImplicitTypeWherePossible, CSharpVSResources.UseVarWhenPossible, s_varWherePossiblePreviewTrue, s_varWherePossiblePreviewFalse, this, optionSet, notificationOptions));
}
//private List<CodeStyleItem> _codeStyleItems;
//public List<CodeStyleItem> CodeStyleItems
//{
// get
// {
// return _codeStyleItems;
// }
//}
//public class CodeStyleItem // TODO: StyleOptionViewModel?
//{
// public CodeStyleItem(string description)
// {
// this.Description = description;
// var selectedPreference = "No";
// this.Preferences = new List<string> { "Yes", selectedPreference };
// this.SelectedPreference = selectedPreference;
// var selectedNotificationPreference = "None";
// this.NotificationPreferences = new List<string> { selectedNotificationPreference, "Info", "Warning", "Error" };
// this.SelectedNotificationPreference = selectedNotificationPreference;
// }
// public string Description { get; set; }
// public List<string> Preferences { get; set; }
// public List<string> NotificationPreferences { get; set; }
// public string SelectedPreference { get; set; }
// public string SelectedNotificationPreference { get; set; }
//}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.Options;
using Microsoft.VisualStudio.Imaging;
using Microsoft.VisualStudio.LanguageServices.Implementation.Utilities;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Options
{
// I'm a row in this table.
internal abstract class AbstractCodeStyleOptionViewModel : AbstractNotifyPropertyChanged
{
// not data binding
private readonly string _truePreview;
private readonly string _falsePreview;
protected AbstractOptionPreviewViewModel Info { get; }
public IOption Option { get; }
// data binding
// this property is temporarily required because not all code styles implement notification preferences.
public abstract bool NotificationsAvailable { get; }
public abstract CodeStylePreference SelectedPreference { get; set; }
public abstract NotificationOptionViewModel SelectedNotificationPreference { get; set; }
public string Description { get; set; }
public double DescriptionMargin { get; set; }
public string GroupName { get; set; }
public List<CodeStylePreference> Preferences { get; set; }
public List<NotificationOptionViewModel> NotificationPreferences { get; set; }
public virtual string GetPreview() => SelectedPreference.IsChecked? _truePreview : _falsePreview;
public AbstractCodeStyleOptionViewModel(
IOption option,
string description,
string truePreview,
string falsePreview,
AbstractOptionPreviewViewModel info,
OptionSet options,
string groupName,
List<CodeStylePreference> preferences = null,
List<NotificationOptionViewModel> notificationPreferences = null)
{
_truePreview = truePreview;
_falsePreview = falsePreview;
Info = info;
Option = option;
Description = description;
Preferences = preferences ?? GetDefaultPreferences();
NotificationPreferences = notificationPreferences ?? GetDefaultNotifications();
DescriptionMargin = 12d;
GroupName = groupName;
}
private static List<NotificationOptionViewModel> GetDefaultNotifications()
{
return new List<NotificationOptionViewModel>
{
new NotificationOptionViewModel(NotificationOption.None, KnownMonikers.None),
new NotificationOptionViewModel(NotificationOption.Info, KnownMonikers.StatusInformation),
new NotificationOptionViewModel(NotificationOption.Warning, KnownMonikers.StatusWarning),
new NotificationOptionViewModel(NotificationOption.Error, KnownMonikers.StatusError)
};
}
private static List<CodeStylePreference> GetDefaultPreferences()
{
return new List<CodeStylePreference>
{
// TODO: move to resx for loc.
new CodeStylePreference("Yes", true),
new CodeStylePreference("No", false),
};
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Options;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Options
{
internal class BooleanCodeStyleOptionViewModel : AbstractCodeStyleOptionViewModel
{
public BooleanCodeStyleOptionViewModel(
IOption option,
string description,
string truePreview,
string falsePreview,
AbstractOptionPreviewViewModel info,
OptionSet options,
string groupName,
List<CodeStylePreference> preferences = null,
List<NotificationOptionViewModel> notificationPreferences = null)
: base(option, description, truePreview, falsePreview, info, options, groupName, preferences, notificationPreferences)
{
var booleanOption = (bool)options.GetOption(new OptionKey(option, option.IsPerLanguage ? info.Language : null));
_selectedPreference = Preferences.Single(c => c.IsChecked == booleanOption);
NotifyPropertyChanged(nameof(SelectedPreference));
}
public override bool NotificationsAvailable => false;
public override NotificationOptionViewModel SelectedNotificationPreference
{
get
{
throw new NotSupportedException();
}
set
{
throw new NotSupportedException();
}
}
private CodeStylePreference _selectedPreference;
public override CodeStylePreference SelectedPreference
{
get
{
return _selectedPreference;
}
set
{
if (SetProperty(ref _selectedPreference, value))
{
Info.SetOptionAndUpdatePreview(_selectedPreference.IsChecked, Option, GetPreview());
}
}
}
}
}
......@@ -55,8 +55,7 @@
HorizontalAlignment="Stretch"
Style="{StaticResource ResourceKey=DataGridStyle}"
SelectionChanged="Options_SelectionChanged"
PreviewKeyDown="Options_PreviewKeyDown"
LoadingRow="Options_LoadingRow">
PreviewKeyDown="Options_PreviewKeyDown">
<!--<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Height" Value="Auto"/>
......@@ -114,7 +113,6 @@
ItemsSource="{Binding Preferences}"
DisplayMemberPath="Name"
SelectedItem="{Binding SelectedPreference, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Visibility="{Binding IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Left"/>
</DataTemplate>
......@@ -129,7 +127,7 @@
<ComboBox
ItemsSource="{Binding NotificationPreferences}"
SelectedItem="{Binding SelectedNotificationPreference,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Visibility="{Binding IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}"
Visibility="{Binding NotificationsAvailable, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Left">
<ComboBox.ItemTemplate>
......
......@@ -28,28 +28,14 @@ internal partial class GridOptionPreviewControl : AbstractOptionPageControl
private void Options_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var dataGrid = (DataGrid)sender;
var codeStyleItem = (SimpleCodeStyleOptionViewModel)dataGrid.SelectedItem;
var codeStyleItem = (AbstractCodeStyleOptionViewModel)dataGrid.SelectedItem;
if (codeStyleItem != null && codeStyleItem.IsVisible)
if (codeStyleItem != null && codeStyleItem.NotificationsAvailable)
{
ViewModel.UpdatePreview(codeStyleItem.GetPreview());
}
}
// TODO: do this with DataBinding.
private void Options_LoadingRow(object sender, DataGridRowEventArgs e)
{
DataGridRow row = e.Row;
if (!((SimpleCodeStyleOptionViewModel)e.Row.Item).IsVisible)
{
// set height for header row.
// the default height won't work well here because this doesn't have combos
// while the other rows have one.
row.Height = 24;
}
}
private void Options_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Space && e.KeyboardDevice.Modifiers == ModifierKeys.None)
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis.CodeStyle;
......@@ -9,22 +10,10 @@
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Options
{
// I'm a row in this table.
internal class SimpleCodeStyleOptionViewModel : AbstractNotifyPropertyChanged
internal class SimpleCodeStyleOptionViewModel : AbstractCodeStyleOptionViewModel
{
private readonly string _truePreview;
private readonly string _falsePreview;
// data binding
public string Description { get; set; }
public double DescriptionMargin { get; set; }
public bool IsVisible { get; set; }
public string GroupName { get; set; }
public List<CodeStylePreference> Preferences { get; set; }
private CodeStylePreference _selectedPreference;
public CodeStylePreference SelectedPreference
public override CodeStylePreference SelectedPreference
{
get
{
......@@ -39,10 +28,8 @@ public CodeStylePreference SelectedPreference
}
}
public List<NotificationOptionViewModel> NotificationPreferences { get; set; }
private NotificationOptionViewModel _selectedNotificationPreference;
public NotificationOptionViewModel SelectedNotificationPreference
public override NotificationOptionViewModel SelectedNotificationPreference
{
get
{
......@@ -58,32 +45,7 @@ public NotificationOptionViewModel SelectedNotificationPreference
}
}
// not data binding
protected AbstractOptionPreviewViewModel Info { get; }
public IOption Option { get; }
//public static SimpleCodeStyleOptionViewModel Header(string text)
//{
// return new SimpleCodeStyleOptionViewModel(text);
//}
internal virtual string GetPreview() => _selectedPreference.IsChecked ? _truePreview : _falsePreview;
//public SimpleCodeStyleOptionViewModel(IOption option, string description, string preview, AbstractOptionPreviewViewModel info, OptionSet options)
// : this(option, description, preview, preview, info, options)
//{
//}
//private SimpleCodeStyleOptionViewModel(string header)
//{
// Description = header;
// Preferences = GetDefaultPreferences();
// NotificationPreferences = GetDefaultNotifications();
// _selectedPreference = null;
// _selectedNotificationPreference = null;
// IsVisible = false;
// DescriptionMargin = default(double);
//}
public override bool NotificationsAvailable => true;
public SimpleCodeStyleOptionViewModel(
IOption option,
......@@ -95,19 +57,8 @@ public NotificationOptionViewModel SelectedNotificationPreference
string groupName,
List<CodeStylePreference> preferences = null,
List<NotificationOptionViewModel> notificationPreferences = null)
: base(option, description, truePreview, falsePreview, info, options, groupName, preferences, notificationPreferences)
{
_truePreview = truePreview;
_falsePreview = falsePreview;
Info = info;
Option = option;
Description = description;
Preferences = preferences ?? GetDefaultPreferences();
NotificationPreferences = notificationPreferences ?? GetDefaultNotifications();
IsVisible = true;
DescriptionMargin = 12d;
GroupName = groupName;
var codeStyleOption = ((SimpleCodeStyleOption)options.GetOption(new OptionKey(option, option.IsPerLanguage ? info.Language : null)));
_selectedPreference = Preferences.Single(c => c.IsChecked == codeStyleOption.IsChecked);
......@@ -117,26 +68,5 @@ public NotificationOptionViewModel SelectedNotificationPreference
NotifyPropertyChanged(nameof(SelectedPreference));
NotifyPropertyChanged(nameof(SelectedNotificationPreference));
}
private static List<NotificationOptionViewModel> GetDefaultNotifications()
{
return new List<NotificationOptionViewModel>
{
new NotificationOptionViewModel(NotificationOption.None, KnownMonikers.None),
new NotificationOptionViewModel(NotificationOption.Info, KnownMonikers.StatusInformation),
new NotificationOptionViewModel(NotificationOption.Warning, KnownMonikers.StatusWarning),
new NotificationOptionViewModel(NotificationOption.Error, KnownMonikers.StatusError)
};
}
private static List<CodeStylePreference> GetDefaultPreferences()
{
return new List<CodeStylePreference>
{
// TODO: move to resx for loc.
new CodeStylePreference("Yes", true),
new CodeStylePreference("No", false),
};
}
}
}
......@@ -310,6 +310,8 @@
<Compile Include="CodeModel\RootCodeModel.cs" />
<Compile Include="CodeModel\SyntaxNodeKey.cs" />
<Compile Include="CodeModel\TextManagerAdapter.cs" />
<Compile Include="Options\AbstractCodeStyleOptionViewModel.cs" />
<Compile Include="Options\BooleanCodeStyleOptionViewModel.cs" />
<Compile Include="Options\CodeStylePreference.cs" />
<Compile Include="Options\Converters\MarginConverter.cs" />
<Compile Include="Options\SimpleCodeStyleOptionViewModel.cs" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册