mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 03:48:56 +00:00
Merge pull request #483 from Artemis-RGB/conditions-ui
Conditions UI revamp
This commit is contained in:
commit
016d39d034
20 files changed
+487
-348
No files matched your search
@@ -6,6 +6,7 @@
|
||||
xmlns:shared="clr-namespace:Artemis.UI.Shared"
|
||||
xmlns:input="clr-namespace:Artemis.UI.Shared.Input"
|
||||
xmlns:s="https://github.com/canton7/Stylet"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance input:DataModelDynamicViewModel}">
|
||||
@@ -24,45 +25,78 @@
|
||||
</DataTrigger>
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
<Style x:Key="DataModelConditionButtonCornerToggle" BasedOn="{StaticResource DataModelConditionButton}" TargetType="Button">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding DisplaySwitchButton}" Value="True">
|
||||
<Setter Property="materialDesign:ButtonAssist.CornerRadius" Value="0 2 2 0" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding DisplaySwitchButton}" Value="False">
|
||||
<Setter Property="materialDesign:ButtonAssist.CornerRadius" Value="2" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Button Background="{Binding ButtonBrush}"
|
||||
BorderBrush="{Binding ButtonBrush}"
|
||||
Style="{StaticResource DataModelConditionButton}"
|
||||
ToolTip="{Binding DisplayPath}"
|
||||
IsEnabled="{Binding IsEnabled}"
|
||||
HorizontalAlignment="Left"
|
||||
Click="PropertyButton_OnClick">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu ItemsSource="{Binding DataModelViewModel.Children}" IsOpen="{Binding IsDataModelViewModelOpen, Mode=OneWayToSource}">
|
||||
<ContextMenu.ItemContainerStyle>
|
||||
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource MaterialDesignMenuItem}">
|
||||
<Setter Property="ItemsSource" Value="{Binding Children}" />
|
||||
<Setter Property="Command" Value="{Binding Data.SelectPropertyCommand, Source={StaticResource DataContextProxy}}" />
|
||||
<Setter Property="CommandParameter" Value="{Binding}" />
|
||||
<Setter Property="CommandTarget" Value="{Binding}" />
|
||||
<Setter Property="IsEnabled" Value="{Binding IsMatchingFilteredTypes}" />
|
||||
<Setter Property="IsSubmenuOpen" Value="{Binding IsVisualizationExpanded, Mode=TwoWay}" />
|
||||
<Setter Property="HeaderTemplate" Value="{StaticResource DataModelDataTemplate}" />
|
||||
</Style>
|
||||
</ContextMenu.ItemContainerStyle>
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
<Grid>
|
||||
<Grid Visibility="{Binding IsValid,Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
||||
<TextBlock Text="{Binding DisplayValue}"
|
||||
Visibility="{Binding DataModelPath, Converter={StaticResource NullToVisibilityConverter}}" />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Style="{StaticResource MaterialDesignFlatDarkBgButton}"
|
||||
Height="22"
|
||||
Padding="0"
|
||||
Width="22"
|
||||
FontSize="12"
|
||||
materialDesign:ButtonAssist.CornerRadius="2 0 0 2"
|
||||
Margin="3 0 -3 0"
|
||||
HorizontalAlignment="Left"
|
||||
ToolTip="Switch to manual input"
|
||||
Command="{s:Action SwitchToStatic}"
|
||||
Visibility="{Binding DisplaySwitchButton, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
||||
<materialDesign:PackIcon Kind="SwapHorizontal" />
|
||||
</Button>
|
||||
<Button Background="{Binding ButtonBrush}"
|
||||
BorderBrush="{Binding ButtonBrush}"
|
||||
Style="{StaticResource DataModelConditionButtonCornerToggle}"
|
||||
ToolTip="{Binding DisplayPath}"
|
||||
IsEnabled="{Binding IsEnabled}"
|
||||
HorizontalAlignment="Left"
|
||||
Click="PropertyButton_OnClick">
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu IsOpen="{Binding IsDataModelViewModelOpen, Mode=OneWayToSource}">
|
||||
<ContextMenu.Resources>
|
||||
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource MaterialDesignMenuItem}">
|
||||
<Setter Property="ItemsSource" Value="{Binding Children}" />
|
||||
<Setter Property="Command" Value="{Binding Data.SelectPropertyCommand, Source={StaticResource DataContextProxy}}" />
|
||||
<Setter Property="CommandParameter" Value="{Binding}" />
|
||||
<Setter Property="CommandTarget" Value="{Binding}" />
|
||||
<Setter Property="IsEnabled" Value="{Binding IsMatchingFilteredTypes}" />
|
||||
<Setter Property="IsSubmenuOpen" Value="{Binding IsVisualizationExpanded, Mode=TwoWay}" />
|
||||
<Setter Property="HeaderTemplate" Value="{StaticResource DataModelDataTemplate}" />
|
||||
</Style>
|
||||
</ContextMenu.Resources>
|
||||
<ContextMenu.ItemsSource>
|
||||
<CompositeCollection>
|
||||
<CollectionContainer Collection="{Binding Data.ExtraDataModelViewModels, Source={StaticResource DataContextProxy}}" />
|
||||
<Separator Visibility="{Binding Data.HasExtraDataModels, Source={StaticResource DataContextProxy}, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}"/>
|
||||
<CollectionContainer Collection="{Binding Data.DataModelViewModel.Children, Source={StaticResource DataContextProxy}}" />
|
||||
</CompositeCollection>
|
||||
</ContextMenu.ItemsSource>
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
<Grid>
|
||||
<Grid Visibility="{Binding IsValid,Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
|
||||
<TextBlock Text="{Binding DisplayValue}"
|
||||
Visibility="{Binding DataModelPath, Converter={StaticResource NullToVisibilityConverter}}" />
|
||||
<TextBlock FontStyle="Italic"
|
||||
Visibility="{Binding DataModelPath, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}">
|
||||
<Run Text="« " /><Run Text="{Binding Placeholder}" /><Run Text=" »" />
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
<TextBlock FontStyle="Italic"
|
||||
Visibility="{Binding DataModelPath, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}">
|
||||
<Run Text="« " /><Run Text="{Binding Placeholder}" /><Run Text=" »" />
|
||||
Visibility="{Binding IsValid, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay}">
|
||||
« Invalid »
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
<TextBlock FontStyle="Italic"
|
||||
Visibility="{Binding IsValid, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay}">
|
||||
« Invalid »
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
</Button>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
</UserControl>
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Timers;
|
||||
using System.Windows.Media;
|
||||
@@ -21,6 +22,7 @@ namespace Artemis.UI.Shared.Input
|
||||
private Brush _buttonBrush = new SolidColorBrush(Color.FromRgb(171, 71, 188));
|
||||
private DataModelPath _dataModelPath;
|
||||
private DataModelPropertiesViewModel _dataModelViewModel;
|
||||
private bool _displaySwitchButton;
|
||||
private Type[] _filterTypes;
|
||||
private bool _isDataModelViewModelOpen;
|
||||
private bool _isEnabled = true;
|
||||
@@ -32,6 +34,7 @@ namespace Artemis.UI.Shared.Input
|
||||
_dataModelUIService = dataModelUIService;
|
||||
_updateTimer = new Timer(500);
|
||||
|
||||
ExtraDataModelViewModels = new BindableCollection<DataModelPropertiesViewModel>();
|
||||
ShowDataModelValues = settingsService.GetSetting<bool>("ProfileEditor.ShowDataModelValues");
|
||||
SelectPropertyCommand = new DelegateCommand(ExecuteSelectPropertyCommand);
|
||||
|
||||
@@ -56,6 +59,12 @@ namespace Artemis.UI.Shared.Input
|
||||
set => SetAndNotify(ref _isEnabled, value);
|
||||
}
|
||||
|
||||
public bool DisplaySwitchButton
|
||||
{
|
||||
get => _displaySwitchButton;
|
||||
set => SetAndNotify(ref _displaySwitchButton, value);
|
||||
}
|
||||
|
||||
public Type[] FilterTypes
|
||||
{
|
||||
get => _filterTypes;
|
||||
@@ -66,6 +75,9 @@ namespace Artemis.UI.Shared.Input
|
||||
}
|
||||
}
|
||||
|
||||
public BindableCollection<DataModelPropertiesViewModel> ExtraDataModelViewModels { get; }
|
||||
public bool HasExtraDataModels => ExtraDataModelViewModels.Any();
|
||||
|
||||
public DelegateCommand SelectPropertyCommand { get; }
|
||||
public PluginSetting<bool> ShowDataModelValues { get; }
|
||||
|
||||
@@ -125,27 +137,23 @@ namespace Artemis.UI.Shared.Input
|
||||
DataModelPath = dataModelPath != null ? new DataModelPath(dataModelPath) : null;
|
||||
}
|
||||
|
||||
public void SwitchToStatic()
|
||||
{
|
||||
ChangeDataModelPath(null);
|
||||
OnPropertySelected(new DataModelInputDynamicEventArgs(null));
|
||||
OnSwitchToStaticRequested();
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
// Get the data models
|
||||
DataModelViewModel = _dataModelUIService.GetPluginDataModelVisualization(_module, true);
|
||||
DataModelViewModel.UpdateRequested += DataModelOnUpdateRequested;
|
||||
|
||||
ExtraDataModelViewModels.CollectionChanged += ExtraDataModelViewModelsOnCollectionChanged;
|
||||
_updateTimer.Start();
|
||||
_updateTimer.Elapsed += OnUpdateTimerOnElapsed;
|
||||
}
|
||||
|
||||
private void DataModelOnUpdateRequested(object sender, EventArgs e)
|
||||
{
|
||||
DataModelViewModel.ApplyTypeFilter(true, FilterTypes);
|
||||
}
|
||||
|
||||
private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
if (IsDataModelViewModelOpen)
|
||||
DataModelViewModel.Update(_dataModelUIService);
|
||||
}
|
||||
|
||||
private void ExecuteSelectPropertyCommand(object context)
|
||||
{
|
||||
if (!(context is DataModelVisualizationViewModel selected))
|
||||
@@ -164,15 +172,47 @@ namespace Artemis.UI.Shared.Input
|
||||
DataModelPath?.Dispose();
|
||||
}
|
||||
|
||||
#region Event handlers
|
||||
|
||||
private void DataModelOnUpdateRequested(object sender, EventArgs e)
|
||||
{
|
||||
DataModelViewModel.ApplyTypeFilter(true, FilterTypes);
|
||||
foreach (DataModelPropertiesViewModel extraDataModelViewModel in ExtraDataModelViewModels)
|
||||
extraDataModelViewModel.ApplyTypeFilter(true, FilterTypes);
|
||||
}
|
||||
|
||||
private void ExtraDataModelViewModelsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
NotifyOfPropertyChange(nameof(HasExtraDataModels));
|
||||
}
|
||||
|
||||
private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
if (!IsDataModelViewModelOpen)
|
||||
return;
|
||||
|
||||
DataModelViewModel.Update(_dataModelUIService);
|
||||
foreach (DataModelPropertiesViewModel extraDataModelViewModel in ExtraDataModelViewModels)
|
||||
extraDataModelViewModel.Update(_dataModelUIService);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
public event EventHandler<DataModelInputDynamicEventArgs> PropertySelected;
|
||||
public event EventHandler SwitchToStaticRequested;
|
||||
|
||||
protected virtual void OnPropertySelected(DataModelInputDynamicEventArgs e)
|
||||
{
|
||||
PropertySelected?.Invoke(this, e);
|
||||
}
|
||||
|
||||
protected virtual void OnSwitchToStaticRequested()
|
||||
{
|
||||
SwitchToStaticRequested?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -22,24 +22,39 @@
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid Margin="3 -4">
|
||||
<Button Style="{StaticResource DataModelConditionButton}"
|
||||
Background="{Binding ButtonBrush}"
|
||||
BorderBrush="{Binding ButtonBrush}"
|
||||
Margin="0 4"
|
||||
Command="{s:Action ActivateInputViewModel}"
|
||||
HorizontalAlignment="Left"
|
||||
IsEnabled="{Binding IsEnabled}"
|
||||
Visibility="{Binding InputViewModel, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}">
|
||||
<Grid>
|
||||
<StackPanel Visibility="{Binding Value, Converter={StaticResource NullToVisibilityConverter}}" Orientation="Horizontal">
|
||||
<ContentControl s:View.Model="{Binding DisplayViewModel}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Visibility="{Binding InputViewModel, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}">
|
||||
<Button Style="{StaticResource MaterialDesignFlatDarkBgButton}"
|
||||
Height="22"
|
||||
Padding="0"
|
||||
Width="22"
|
||||
FontSize="12"
|
||||
materialDesign:ButtonAssist.CornerRadius="2 0 0 2"
|
||||
Margin="0 0 -3 0"
|
||||
HorizontalAlignment="Left"
|
||||
ToolTip="Switch to data model value"
|
||||
Command="{s:Action SwitchToDynamic}">
|
||||
<materialDesign:PackIcon Kind="SwapHorizontal" />
|
||||
</Button>
|
||||
<Button Style="{StaticResource DataModelConditionButton}"
|
||||
materialDesign:ButtonAssist.CornerRadius="0 2 2 0"
|
||||
Background="{Binding ButtonBrush}"
|
||||
BorderBrush="{Binding ButtonBrush}"
|
||||
Command="{s:Action ActivateInputViewModel}"
|
||||
HorizontalAlignment="Left"
|
||||
IsEnabled="{Binding IsEnabled}"
|
||||
ToolTip="Click to edit value">
|
||||
<Grid>
|
||||
<StackPanel Visibility="{Binding Value, Converter={StaticResource NullToVisibilityConverter}}" Orientation="Horizontal">
|
||||
<ContentControl s:View.Model="{Binding DisplayViewModel}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock FontStyle="Italic" Visibility="{Binding Value, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}">
|
||||
<Run Text="« " /><Run Text="{Binding Placeholder}" /><Run Text=" »" />
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
</Button>
|
||||
<TextBlock FontStyle="Italic" Visibility="{Binding Value, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}">
|
||||
<Run Text="« " /><Run Text="{Binding Placeholder}" /><Run Text=" »" />
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
<Border BorderBrush="{Binding ButtonBrush}"
|
||||
Background="{DynamicResource MaterialDesignPaper}"
|
||||
Visibility="{Binding InputViewModel, Converter={StaticResource NullToVisibilityConverter}}"
|
||||
|
||||
@@ -17,11 +17,11 @@ namespace Artemis.UI.Shared.Input
|
||||
private Brush _buttonBrush = new SolidColorBrush(Color.FromRgb(171, 71, 188));
|
||||
private DataModelDisplayViewModel _displayViewModel;
|
||||
private DataModelInputViewModel _inputViewModel;
|
||||
private bool _isEnabled;
|
||||
private string _placeholder = "Enter a value";
|
||||
private DataModelPropertyAttribute _targetDescription;
|
||||
private Type _targetType;
|
||||
private object _value;
|
||||
private bool _isEnabled;
|
||||
|
||||
internal DataModelStaticViewModel(Type targetType, DataModelPropertyAttribute targetDescription, IDataModelUIService dataModelUIService)
|
||||
{
|
||||
@@ -32,7 +32,7 @@ namespace Artemis.UI.Shared.Input
|
||||
TargetDescription = targetDescription;
|
||||
IsEnabled = TargetType != null;
|
||||
DisplayViewModel = _dataModelUIService.GetDataModelDisplayViewModel(TargetType ?? typeof(object), TargetDescription, true);
|
||||
|
||||
|
||||
if (_rootView != null)
|
||||
{
|
||||
_rootView.MouseUp += RootViewOnMouseUp;
|
||||
@@ -45,7 +45,7 @@ namespace Artemis.UI.Shared.Input
|
||||
get => _buttonBrush;
|
||||
set => SetAndNotify(ref _buttonBrush, value);
|
||||
}
|
||||
|
||||
|
||||
public DataModelDisplayViewModel DisplayViewModel
|
||||
{
|
||||
get => _displayViewModel;
|
||||
@@ -92,19 +92,6 @@ namespace Artemis.UI.Shared.Input
|
||||
private set => SetAndNotify(ref _isEnabled, value);
|
||||
}
|
||||
|
||||
#region IDisposable
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_rootView != null)
|
||||
{
|
||||
_rootView.MouseUp -= RootViewOnMouseUp;
|
||||
_rootView.KeyUp -= RootViewOnKeyUp;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void ActivateInputViewModel()
|
||||
{
|
||||
InputViewModel = _dataModelUIService.GetDataModelInputViewModel(
|
||||
@@ -127,16 +114,21 @@ namespace Artemis.UI.Shared.Input
|
||||
ApplyFreeInput(null, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the type changed, reset to the default type
|
||||
if (Value == null || !target.IsCastableFrom(Value.GetType()))
|
||||
{
|
||||
// Force the VM to close if it was open and apply the new value
|
||||
ApplyFreeInput(target.GetDefault(), true);
|
||||
}
|
||||
|
||||
// If the type changed, reset to the default type
|
||||
if (Value == null || !TargetType.IsCastableFrom(Value.GetType()))
|
||||
// Force the VM to close if it was open and apply the new value
|
||||
ApplyFreeInput(TargetType.GetDefault(), true);
|
||||
}
|
||||
|
||||
|
||||
public void SwitchToDynamic()
|
||||
{
|
||||
InputViewModel?.Cancel();
|
||||
ApplyFreeInput(TargetType.GetDefault(), true);
|
||||
|
||||
OnSwitchToDynamicRequested();
|
||||
}
|
||||
|
||||
private void ApplyFreeInput(object value, bool submitted)
|
||||
{
|
||||
if (submitted)
|
||||
@@ -146,6 +138,19 @@ namespace Artemis.UI.Shared.Input
|
||||
Value = value;
|
||||
}
|
||||
|
||||
#region IDisposable
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_rootView != null)
|
||||
{
|
||||
_rootView.MouseUp -= RootViewOnMouseUp;
|
||||
_rootView.KeyUp -= RootViewOnKeyUp;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event handlers
|
||||
|
||||
private void RootViewOnKeyUp(object sender, KeyEventArgs e)
|
||||
@@ -173,12 +178,18 @@ namespace Artemis.UI.Shared.Input
|
||||
#region Events
|
||||
|
||||
public event EventHandler<DataModelInputStaticEventArgs> ValueUpdated;
|
||||
public event EventHandler SwitchToDynamicRequested;
|
||||
|
||||
protected virtual void OnValueUpdated(DataModelInputStaticEventArgs e)
|
||||
{
|
||||
ValueUpdated?.Invoke(this, e);
|
||||
}
|
||||
|
||||
protected virtual void OnSwitchToDynamicRequested()
|
||||
{
|
||||
SwitchToDynamicRequested?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Modules;
|
||||
using Ninject;
|
||||
@@ -13,7 +14,7 @@ namespace Artemis.UI.Shared.Services
|
||||
ILayerProperty SelectedDataBinding { get; }
|
||||
TimeSpan CurrentTime { get; set; }
|
||||
int PixelsPerSecond { get; set; }
|
||||
IReadOnlyList<PropertyInputRegistration> RegisteredPropertyEditors { get; }
|
||||
ReadOnlyCollection<PropertyInputRegistration> RegisteredPropertyEditors { get; }
|
||||
IKernel Kernel { get; }
|
||||
void ChangeSelectedProfile(Profile profile);
|
||||
void UpdateSelectedProfile();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Modules;
|
||||
@@ -32,7 +33,7 @@ namespace Artemis.UI.Shared.Services
|
||||
}
|
||||
|
||||
public IKernel Kernel { get; }
|
||||
public IReadOnlyList<PropertyInputRegistration> RegisteredPropertyEditors => _registeredPropertyEditors.AsReadOnly();
|
||||
public ReadOnlyCollection<PropertyInputRegistration> RegisteredPropertyEditors => _registeredPropertyEditors.AsReadOnly();
|
||||
public Profile SelectedProfile { get; private set; }
|
||||
public RenderProfileElement SelectedProfileElement { get; private set; }
|
||||
public ILayerProperty SelectedDataBinding { get; private set; }
|
||||
|
||||
Reference in new issue
Block a user