mirror of
https://gitee.com/handyorg/HandyControl.git
synced 2024-11-30 02:48:03 +08:00
Merge pull request #409 from HandyOrg/add-PropertyEditor
Add property editor
This commit is contained in:
commit
e57340f1c2
@ -1,9 +1,9 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<UseWPF>true</UseWPF>
|
||||
<Version>2.5.0.1</Version>
|
||||
<FileVersion>2.5.0.1</FileVersion>
|
||||
<AssemblyVersion>2.5.0.1</AssemblyVersion>
|
||||
<Version>3.0.0.0</Version>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<Copyright>Copyright © HandyOrg 2018-2020</Copyright>
|
||||
<Authors>HandyOrg</Authors>
|
||||
|
@ -313,6 +313,9 @@
|
||||
<Resource Include="..\..\Shared\HandyControlDemo_Shared\Resources\Img\LeftMainContent\RadioButton_16x.png">
|
||||
<Link>Resources\Img\LeftMainContent\RadioButton_16x.png</Link>
|
||||
</Resource>
|
||||
<Resource Include="..\..\Shared\HandyControlDemo_Shared\Resources\Img\LeftMainContent\PropertyGridEditorPart_16x.png">
|
||||
<Link>Resources\Img\LeftMainContent\PropertyGridEditorPart_16x.png</Link>
|
||||
</Resource>
|
||||
<Resource Include="..\..\Shared\HandyControlDemo_Shared\Resources\Img\LeftMainContent\RepeatButton_16x.png">
|
||||
<Link>Resources\Img\LeftMainContent\RepeatButton_16x.png</Link>
|
||||
</Resource>
|
||||
|
@ -313,6 +313,9 @@
|
||||
<Resource Include="..\..\Shared\HandyControlDemo_Shared\Resources\Img\LeftMainContent\RadioButton_16x.png">
|
||||
<Link>Resources\Img\LeftMainContent\RadioButton_16x.png</Link>
|
||||
</Resource>
|
||||
<Resource Include="..\..\Shared\HandyControlDemo_Shared\Resources\Img\LeftMainContent\PropertyGridEditorPart_16x.png">
|
||||
<Link>Resources\Img\LeftMainContent\PropertyGridEditorPart_16x.png</Link>
|
||||
</Resource>
|
||||
<Resource Include="..\..\Shared\HandyControlDemo_Shared\Resources\Img\LeftMainContent\RepeatButton_16x.png">
|
||||
<Link>Resources\Img\LeftMainContent\RepeatButton_16x.png</Link>
|
||||
</Resource>
|
||||
|
@ -177,6 +177,9 @@
|
||||
<Resource Include="..\..\Shared\HandyControlDemo_Shared\UserControl\Controls\ProgressButtonDemoCtl.xaml">
|
||||
<Link>UserControl\Controls\ProgressButtonDemoCtl.xaml</Link>
|
||||
</Resource>
|
||||
<Resource Include="..\..\Shared\HandyControlDemo_Shared\UserControl\Controls\PropertyGridDemoCtl.xaml">
|
||||
<Link>UserControl\Controls\PropertyGridDemoCtl.xaml</Link>
|
||||
</Resource>
|
||||
<Resource Include="..\..\Shared\HandyControlDemo_Shared\UserControl\Controls\RangeSliderDemoCtl.xaml">
|
||||
<Link>UserControl\Controls\RangeSliderDemoCtl.xaml</Link>
|
||||
</Resource>
|
||||
@ -572,6 +575,10 @@
|
||||
<Link>UserControl\Controls\ProgressButtonDemoCtl.xaml.cs</Link>
|
||||
<DependentUpon>ProgressButtonDemoCtl.xaml</DependentUpon>
|
||||
</Resource>
|
||||
<Resource Include="..\..\Shared\HandyControlDemo_Shared\UserControl\Controls\PropertyGridDemoCtl.xaml.cs">
|
||||
<Link>UserControl\Controls\PropertyGridDemoCtl.xaml.cs</Link>
|
||||
<DependentUpon>PropertyGridDemoCtl.xaml</DependentUpon>
|
||||
</Resource>
|
||||
<Resource Include="..\..\Shared\HandyControlDemo_Shared\UserControl\Controls\RangeSliderDemoCtl.xaml.cs">
|
||||
<Link>UserControl\Controls\RangeSliderDemoCtl.xaml.cs</Link>
|
||||
<DependentUpon>RangeSliderDemoCtl.xaml</DependentUpon>
|
||||
|
@ -40,6 +40,7 @@
|
||||
"selectedIndex": 0,
|
||||
"demoItemList": [
|
||||
[ "FloatingBlock", "FloatingBlockDemoCtl", "thumbs_up", "" ],
|
||||
[ "PropertyGrid", "PropertyGridDemoCtl", "PropertyGridEditorPart_16x", "1" ],
|
||||
[ "ImageBlock", "ImageBlockDemoCtl", "ImageStack_16x", "" ],
|
||||
[ "Magnifier", "MagnifierDemoCtl", "Search_16x", "" ],
|
||||
[ "Gravatar", "GravatarDemoCtl", "User_16x", "" ],
|
||||
@ -55,7 +56,7 @@
|
||||
[ "TextBox", "TextBoxDemoCtl", "TextBox_16x", "" ],
|
||||
[ "ComboBox", "ComboBoxDemoCtl", "ComboBox_16x", "" ],
|
||||
[ "PasswordBox", "PasswordBoxDemoCtl", "PasswordBox_16x", "" ],
|
||||
[ "PinBox", "PinBoxDemoCtl", "Ellipsis_16x", "1" ],
|
||||
[ "PinBox", "PinBoxDemoCtl", "Ellipsis_16x", "" ],
|
||||
[ "DatePicker", "DatePickerDemoCtl", "DatePicker_16x", "" ],
|
||||
[ "Clock", "ClockDemoCtl", "Time_color_16x", "" ],
|
||||
[ "TimePicker", "TimePickerDemoCtl", "TimePicker_16x", "" ],
|
||||
|
@ -0,0 +1,25 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace HandyControlDemo.Data
|
||||
{
|
||||
public class PropertyGridDemoModel
|
||||
{
|
||||
[Category("Info")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Category("Achievement")]
|
||||
public int Score { get; set; }
|
||||
|
||||
[Category("Achievement")]
|
||||
public bool IsPassed { get; set; }
|
||||
|
||||
[Category("Info")]
|
||||
public Gender Gender { get; set; }
|
||||
}
|
||||
|
||||
public enum Gender
|
||||
{
|
||||
Male,
|
||||
Female
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Data\Model\CardModel.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Data\Model\ChatInfoModel.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Data\Model\AvatarModel.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Data\Model\PropertyGridDemoModel.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Data\Model\CoverViewDemoModel.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Data\Model\DemoDataModel.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Data\Model\DemoInfoModel.cs" />
|
||||
@ -84,6 +85,9 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)UserControl\Controls\PinBoxDemoCtl.xaml.cs">
|
||||
<DependentUpon>PinBoxDemoCtl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)UserControl\Controls\PropertyGridDemoCtl.xaml.cs">
|
||||
<DependentUpon>PropertyGridDemoCtl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)UserControl\Controls\RangeSliderDemoCtl.xaml.cs">
|
||||
<DependentUpon>RangeSliderDemoCtl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@ -548,6 +552,10 @@
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="$(MSBuildThisFileDirectory)UserControl\Controls\PropertyGridDemoCtl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="$(MSBuildThisFileDirectory)UserControl\Controls\RangeSliderDemoCtl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
@ -1338,6 +1338,17 @@ namespace HandyControlDemo.Properties.Langs {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 属性编辑器 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string PropertyGrid
|
||||
{
|
||||
get
|
||||
{
|
||||
return ResourceManager.GetString("PropertyGrid", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 按住说话 的本地化字符串。
|
||||
/// </summary>
|
||||
|
@ -750,4 +750,7 @@
|
||||
<data name="LangComment" xml:space="preserve">
|
||||
<value>Looks up a localized string similar to "{0}".</value>
|
||||
</data>
|
||||
<data name="PropertyGrid" xml:space="preserve">
|
||||
<value>PropertyGrid</value>
|
||||
</data>
|
||||
</root>
|
@ -750,4 +750,7 @@
|
||||
<data name="LangComment" xml:space="preserve">
|
||||
<value>Looks up a localized string similar to "{0}".</value>
|
||||
</data>
|
||||
<data name="PropertyGrid" xml:space="preserve">
|
||||
<value>PropertyGrid</value>
|
||||
</data>
|
||||
</root>
|
@ -750,4 +750,7 @@
|
||||
<data name="LangComment" xml:space="preserve">
|
||||
<value>Looks up a localized string similar to "{0}".</value>
|
||||
</data>
|
||||
<data name="PropertyGrid" xml:space="preserve">
|
||||
<value>PropertyGrid</value>
|
||||
</data>
|
||||
</root>
|
@ -750,4 +750,7 @@
|
||||
<data name="LangComment" xml:space="preserve">
|
||||
<value>Looks up a localized string similar to "{0}".</value>
|
||||
</data>
|
||||
<data name="PropertyGrid" xml:space="preserve">
|
||||
<value>PropertyGrid</value>
|
||||
</data>
|
||||
</root>
|
@ -750,4 +750,7 @@
|
||||
<data name="LangComment" xml:space="preserve">
|
||||
<value>查找类似 {0} 的本地化字符串。</value>
|
||||
</data>
|
||||
<data name="PropertyGrid" xml:space="preserve">
|
||||
<value>属性编辑器</value>
|
||||
</data>
|
||||
</root>
|
@ -750,4 +750,7 @@
|
||||
<data name="LangComment" xml:space="preserve">
|
||||
<value>Looks up a localized string similar to "{0}".</value>
|
||||
</data>
|
||||
<data name="PropertyGrid" xml:space="preserve">
|
||||
<value>PropertyGrid</value>
|
||||
</data>
|
||||
</root>
|
@ -750,4 +750,7 @@
|
||||
<data name="LangComment" xml:space="preserve">
|
||||
<value>Looks up a localized string similar to "{0}".</value>
|
||||
</data>
|
||||
<data name="PropertyGrid" xml:space="preserve">
|
||||
<value>PropertyGrid</value>
|
||||
</data>
|
||||
</root>
|
@ -179,7 +179,8 @@ namespace HandyControlDemo.Properties.Langs
|
||||
OnPropertyChanged(nameof(ProgressBar));
|
||||
OnPropertyChanged(nameof(ProgressButton));
|
||||
OnPropertyChanged(nameof(Project));
|
||||
OnPropertyChanged(nameof(PushToTalk));
|
||||
OnPropertyChanged(nameof(PropertyGrid));
|
||||
OnPropertyChanged(nameof(PushToTalk));
|
||||
OnPropertyChanged(nameof(QQGroup));
|
||||
OnPropertyChanged(nameof(RadioButton));
|
||||
OnPropertyChanged(nameof(RangeSlider));
|
||||
@ -960,6 +961,11 @@ namespace HandyControlDemo.Properties.Langs
|
||||
/// </summary>
|
||||
public string Project => Lang.Project;
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 属性编辑器 的本地化字符串。
|
||||
/// </summary>
|
||||
public string PropertyGrid => Lang.PropertyGrid;
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 按住说话 的本地化字符串。
|
||||
/// </summary>
|
||||
@ -2024,6 +2030,11 @@ namespace HandyControlDemo.Properties.Langs
|
||||
/// </summary>
|
||||
public static string Project = nameof(Project);
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 属性编辑器 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string PropertyGrid = nameof(PropertyGrid);
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 按住说话 的本地化字符串。
|
||||
/// </summary>
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 173 B |
@ -0,0 +1,22 @@
|
||||
<UserControl x:Class="HandyControlDemo.UserControl.PropertyGridDemoCtl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||
Background="{DynamicResource RegionBrush}"
|
||||
DataContext="{Binding RelativeSource={RelativeSource Self}}">
|
||||
<hc:TransitioningContentControl>
|
||||
<Grid Margin="22">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<hc:PropertyGrid Width="500" SelectedObject="{Binding DemoModel}"/>
|
||||
<StackPanel Grid.Row="1" Margin="10,16,10,10">
|
||||
<TextBox hc:TitleElement.Title="Name" hc:TitleElement.TitlePlacement="Left" Style="{StaticResource TextBoxExtend}" Text="{Binding DemoModel.Name,Mode=OneWay}" IsReadOnly="True"/>
|
||||
<TextBox hc:TitleElement.Title="Gender" hc:TitleElement.TitlePlacement="Left" Style="{StaticResource TextBoxExtend}" Text="{Binding DemoModel.Gender,Mode=OneWay}" IsReadOnly="True" Margin="0,6,0,0"/>
|
||||
<TextBox hc:TitleElement.Title="Score" hc:TitleElement.TitlePlacement="Left" Style="{StaticResource TextBoxExtend}" Text="{Binding DemoModel.Score,Mode=OneWay}" IsReadOnly="True" Margin="0,6,0,0"/>
|
||||
<TextBox hc:TitleElement.Title="IsPassed" hc:TitleElement.TitlePlacement="Left" Style="{StaticResource TextBoxExtend}" Text="{Binding DemoModel.IsPassed,Mode=OneWay}" IsReadOnly="True" Margin="0,6,0,0"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</hc:TransitioningContentControl>
|
||||
</UserControl>
|
@ -0,0 +1,30 @@
|
||||
using System.Windows;
|
||||
using HandyControlDemo.Data;
|
||||
|
||||
namespace HandyControlDemo.UserControl
|
||||
{
|
||||
public partial class PropertyGridDemoCtl
|
||||
{
|
||||
public PropertyGridDemoCtl()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
DemoModel = new PropertyGridDemoModel
|
||||
{
|
||||
Name = "TestName",
|
||||
Gender = Gender.Female,
|
||||
IsPassed = true,
|
||||
Score = 98
|
||||
};
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty DemoModelProperty = DependencyProperty.Register(
|
||||
"DemoModel", typeof(PropertyGridDemoModel), typeof(PropertyGridDemoCtl), new PropertyMetadata(default(PropertyGridDemoModel)));
|
||||
|
||||
public PropertyGridDemoModel DemoModel
|
||||
{
|
||||
get => (PropertyGridDemoModel) GetValue(DemoModelProperty);
|
||||
set => SetValue(DemoModelProperty, value);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
public class DatePropertyEditor : PropertyEditorBase
|
||||
{
|
||||
public override FrameworkElement CreateElement(PropertyItem propertyItem) => new DateTimePicker
|
||||
{
|
||||
IsEnabled = !propertyItem.IsReadOnly
|
||||
};
|
||||
|
||||
public override DependencyProperty GetDependencyProperty() => System.Windows.Controls.DatePicker.SelectedDateProperty;
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
public class DateTimePropertyEditor : PropertyEditorBase
|
||||
{
|
||||
public override FrameworkElement CreateElement(PropertyItem propertyItem) => new DateTimePicker
|
||||
{
|
||||
IsEnabled = !propertyItem.IsReadOnly
|
||||
};
|
||||
|
||||
public override DependencyProperty GetDependencyProperty() => DateTimePicker.SelectedDateTimeProperty;
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls.Primitives;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
public class EnumPropertyEditor : PropertyEditorBase
|
||||
{
|
||||
public override FrameworkElement CreateElement(PropertyItem propertyItem) => new System.Windows.Controls.ComboBox
|
||||
{
|
||||
IsEnabled = !propertyItem.IsReadOnly,
|
||||
ItemsSource = Enum.GetValues(propertyItem.PropertyType)
|
||||
};
|
||||
|
||||
public override DependencyProperty GetDependencyProperty() => Selector.SelectedValueProperty;
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
public class NumberPropertyEditor : PropertyEditorBase
|
||||
{
|
||||
public NumberPropertyEditor(double minimum, double maximum)
|
||||
{
|
||||
Minimum = minimum;
|
||||
Maximum = maximum;
|
||||
}
|
||||
|
||||
public double Minimum { get; set; }
|
||||
|
||||
public double Maximum { get; set; }
|
||||
|
||||
public override FrameworkElement CreateElement(PropertyItem propertyItem)
|
||||
{
|
||||
var numericUpDown = new NumericUpDown
|
||||
{
|
||||
IsReadOnly = propertyItem.IsReadOnly,
|
||||
Minimum = Minimum,
|
||||
Maximum = Maximum
|
||||
};
|
||||
|
||||
numericUpDown.SetBinding(NumericUpDown.ValueProperty, CreateBinding(propertyItem));
|
||||
|
||||
return numericUpDown;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
public class NumberPropertyEditor : PropertyEditorBase
|
||||
{
|
||||
public NumberPropertyEditor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public NumberPropertyEditor(double minimum, double maximum)
|
||||
{
|
||||
Minimum = minimum;
|
||||
Maximum = maximum;
|
||||
}
|
||||
|
||||
public double Minimum { get; set; }
|
||||
|
||||
public double Maximum { get; set; }
|
||||
|
||||
public override FrameworkElement CreateElement(PropertyItem propertyItem) => new NumericUpDown
|
||||
{
|
||||
IsReadOnly = propertyItem.IsReadOnly,
|
||||
Minimum = Minimum,
|
||||
Maximum = Maximum
|
||||
};
|
||||
|
||||
public override DependencyProperty GetDependencyProperty() => NumericUpDown.ValueProperty;
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
public class PlainTextPropertyEditor : PropertyEditorBase
|
||||
{
|
||||
public override FrameworkElement CreateElement(PropertyItem propertyItem) => new System.Windows.Controls.TextBox
|
||||
{
|
||||
IsReadOnly = propertyItem.IsReadOnly
|
||||
};
|
||||
|
||||
public override DependencyProperty GetDependencyProperty() => System.Windows.Controls.TextBox.TextProperty;
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
public abstract class PropertyEditorBase : FrameworkElement
|
||||
{
|
||||
public abstract FrameworkElement CreateElement(PropertyItem propertyItem);
|
||||
|
||||
public virtual void CreateBinding(PropertyItem propertyItem, FrameworkElement element) =>
|
||||
BindingOperations.SetBinding(element, GetDependencyProperty(),
|
||||
new Binding($"({propertyItem.PropertyName})")
|
||||
{
|
||||
Source = propertyItem.Value,
|
||||
Mode = GetBindingMode(propertyItem),
|
||||
UpdateSourceTrigger = GetUpdateSourceTrigger(propertyItem),
|
||||
Converter = GetConverter(propertyItem)
|
||||
});
|
||||
|
||||
public abstract DependencyProperty GetDependencyProperty();
|
||||
|
||||
public virtual BindingMode GetBindingMode(PropertyItem propertyItem) => propertyItem.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay;
|
||||
|
||||
public virtual UpdateSourceTrigger GetUpdateSourceTrigger(PropertyItem propertyItem) => UpdateSourceTrigger.PropertyChanged;
|
||||
|
||||
protected virtual IValueConverter GetConverter(PropertyItem propertyItem) => null;
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using HandyControl.Tools;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
public class ReadOnlyTextPropertyEditor : PropertyEditorBase
|
||||
{
|
||||
public override FrameworkElement CreateElement(PropertyItem propertyItem) => new System.Windows.Controls.TextBox
|
||||
{
|
||||
IsReadOnly = true
|
||||
};
|
||||
|
||||
public override DependencyProperty GetDependencyProperty() => System.Windows.Controls.TextBox.TextProperty;
|
||||
|
||||
public override BindingMode GetBindingMode(PropertyItem propertyItem) => BindingMode.OneWay;
|
||||
|
||||
protected override IValueConverter GetConverter(PropertyItem propertyItem) => ResourceHelper.GetResource<IValueConverter>("Object2StringConverter");
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
public class PlainTextPropertyEditor : PropertyEditorBase
|
||||
{
|
||||
public override FrameworkElement CreateElement(PropertyItem propertyItem)
|
||||
{
|
||||
var textbox = new System.Windows.Controls.TextBox
|
||||
{
|
||||
IsReadOnly = propertyItem.IsReadOnly
|
||||
};
|
||||
|
||||
textbox.SetBinding(System.Windows.Controls.TextBox.TextProperty, CreateBinding(propertyItem));
|
||||
|
||||
return textbox;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using HandyControl.Tools;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
public class SwitchPropertyEditor : PropertyEditorBase
|
||||
{
|
||||
public override FrameworkElement CreateElement(PropertyItem propertyItem) => new ToggleButton
|
||||
{
|
||||
Style = ResourceHelper.GetResource<Style>("ToggleButtonSwitch"),
|
||||
HorizontalAlignment = HorizontalAlignment.Left,
|
||||
IsEnabled = !propertyItem.IsReadOnly
|
||||
};
|
||||
|
||||
public override DependencyProperty GetDependencyProperty() => ToggleButton.IsCheckedProperty;
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
public class TimePropertyEditor : PropertyEditorBase
|
||||
{
|
||||
public override FrameworkElement CreateElement(PropertyItem propertyItem) => new DateTimePicker
|
||||
{
|
||||
IsEnabled = !propertyItem.IsReadOnly
|
||||
};
|
||||
|
||||
public override DependencyProperty GetDependencyProperty() => TimePicker.SelectedTimeProperty;
|
||||
}
|
||||
}
|
@ -0,0 +1,189 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using HandyControl.Data;
|
||||
using HandyControl.Interactivity;
|
||||
using HandyControl.Tools.Extension;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
[TemplatePart(Name = ElementItemsControl, Type = typeof(ItemsControl))]
|
||||
[TemplatePart(Name = ElementSearchBar, Type = typeof(SearchBar))]
|
||||
public class PropertyGrid : Control
|
||||
{
|
||||
private const string ElementItemsControl = "PART_ItemsControl";
|
||||
|
||||
private const string ElementSearchBar = "PART_SearchBar";
|
||||
|
||||
private ItemsControl _itemsControl;
|
||||
|
||||
private ICollectionView _dataView;
|
||||
|
||||
private SearchBar _searchBar;
|
||||
|
||||
private string _searchKey;
|
||||
|
||||
public PropertyGrid()
|
||||
{
|
||||
CommandBindings.Add(new CommandBinding(ControlCommands.SortByCategory, SortByCategory));
|
||||
CommandBindings.Add(new CommandBinding(ControlCommands.SortByName, SortByName));
|
||||
}
|
||||
|
||||
public virtual PropertyResolver PropertyResolver { get; } = new PropertyResolver();
|
||||
|
||||
public static readonly RoutedEvent SelectedObjectChangedEvent =
|
||||
EventManager.RegisterRoutedEvent("SelectedObjectChanged", RoutingStrategy.Bubble,
|
||||
typeof(RoutedPropertyChangedEventHandler<object>), typeof(PropertyGrid));
|
||||
|
||||
public event RoutedPropertyChangedEventHandler<object> SelectedObjectChanged
|
||||
{
|
||||
add => AddHandler(SelectedObjectChangedEvent, value);
|
||||
remove => RemoveHandler(SelectedObjectChangedEvent, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty SelectedObjectProperty = DependencyProperty.Register(
|
||||
"SelectedObject", typeof(object), typeof(PropertyGrid), new PropertyMetadata(default, OnSelectedObjectChanged));
|
||||
|
||||
private static void OnSelectedObjectChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var ctl = (PropertyGrid)d;
|
||||
ctl.OnSelectedObjectChanged(e.OldValue, e.NewValue);
|
||||
}
|
||||
|
||||
public object SelectedObject
|
||||
{
|
||||
get => GetValue(SelectedObjectProperty);
|
||||
set => SetValue(SelectedObjectProperty, value);
|
||||
}
|
||||
|
||||
protected virtual void OnSelectedObjectChanged(object oldValue, object newValue)
|
||||
{
|
||||
UpdateItems(newValue);
|
||||
RaiseEvent(new RoutedPropertyChangedEventArgs<object>(oldValue, newValue, SelectedObjectChangedEvent));
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register(
|
||||
"Description", typeof(string), typeof(PropertyGrid), new PropertyMetadata(default(string)));
|
||||
|
||||
public string Description
|
||||
{
|
||||
get => (string)GetValue(DescriptionProperty);
|
||||
set => SetValue(DescriptionProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty MaxTitleWidthProperty = DependencyProperty.Register(
|
||||
"MaxTitleWidth", typeof(double), typeof(PropertyGrid), new PropertyMetadata(default(double)));
|
||||
|
||||
public double MaxTitleWidth
|
||||
{
|
||||
get => (double) GetValue(MaxTitleWidthProperty);
|
||||
set => SetValue(MaxTitleWidthProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty MinTitleWidthProperty = DependencyProperty.Register(
|
||||
"MinTitleWidth", typeof(double), typeof(PropertyGrid), new PropertyMetadata(default(double)));
|
||||
|
||||
public double MinTitleWidth
|
||||
{
|
||||
get => (double) GetValue(MinTitleWidthProperty);
|
||||
set => SetValue(MinTitleWidthProperty, value);
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
if (_searchBar != null)
|
||||
{
|
||||
_searchBar.SearchStarted -= SearchBar_SearchStarted;
|
||||
}
|
||||
|
||||
base.OnApplyTemplate();
|
||||
|
||||
_itemsControl = GetTemplateChild(ElementItemsControl) as ItemsControl;
|
||||
_searchBar = GetTemplateChild(ElementSearchBar) as SearchBar;
|
||||
|
||||
if (_searchBar != null)
|
||||
{
|
||||
_searchBar.SearchStarted += SearchBar_SearchStarted;
|
||||
}
|
||||
|
||||
UpdateItems(SelectedObject);
|
||||
}
|
||||
|
||||
private void UpdateItems(object obj)
|
||||
{
|
||||
if (obj == null || _itemsControl == null) return;
|
||||
|
||||
_dataView = CollectionViewSource.GetDefaultView(TypeDescriptor.GetProperties(obj).OfType<PropertyDescriptor>()
|
||||
.Where(item => PropertyResolver.ResolveIsBrowsable(item)).Select(CreatePropertyItem)
|
||||
.Do(item => item.InitElement()));
|
||||
|
||||
SortByCategory(null, null);
|
||||
_itemsControl.ItemsSource = _dataView;
|
||||
}
|
||||
|
||||
private void SortByCategory(object sender, ExecutedRoutedEventArgs e)
|
||||
{
|
||||
using (_dataView.DeferRefresh())
|
||||
{
|
||||
_dataView.GroupDescriptions.Clear();
|
||||
_dataView.SortDescriptions.Clear();
|
||||
_dataView.SortDescriptions.Add(new SortDescription(PropertyItem.CategoryProperty.Name, ListSortDirection.Ascending));
|
||||
_dataView.SortDescriptions.Add(new SortDescription(PropertyItem.PropertyNameProperty.Name, ListSortDirection.Ascending));
|
||||
_dataView.GroupDescriptions.Add(new PropertyGroupDescription(PropertyItem.CategoryProperty.Name));
|
||||
}
|
||||
}
|
||||
|
||||
private void SortByName(object sender, ExecutedRoutedEventArgs e)
|
||||
{
|
||||
using (_dataView.DeferRefresh())
|
||||
{
|
||||
_dataView.GroupDescriptions.Clear();
|
||||
_dataView.SortDescriptions.Clear();
|
||||
_dataView.SortDescriptions.Add(new SortDescription(PropertyItem.PropertyNameProperty.Name, ListSortDirection.Ascending));
|
||||
}
|
||||
}
|
||||
|
||||
private void SearchBar_SearchStarted(object sender, FunctionEventArgs<string> e)
|
||||
{
|
||||
_searchKey = e.Info;
|
||||
if (string.IsNullOrEmpty(_searchKey))
|
||||
{
|
||||
foreach (UIElement item in _dataView)
|
||||
{
|
||||
item.Show();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (PropertyItem item in _dataView)
|
||||
{
|
||||
item.Show(item.PropertyName.ToLower().Contains(_searchKey) || item.DisplayName.ToLower().Contains(_searchKey));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual PropertyItem CreatePropertyItem(PropertyDescriptor propertyDescriptor) => new PropertyItem
|
||||
{
|
||||
Category = PropertyResolver.ResolveCategory(propertyDescriptor),
|
||||
DisplayName = PropertyResolver.ResolveDisplayName(propertyDescriptor),
|
||||
Description = PropertyResolver.ResolveDescription(propertyDescriptor),
|
||||
IsReadOnly = PropertyResolver.ResolveIsReadOnly(propertyDescriptor),
|
||||
DefaultValue = PropertyResolver.ResolveDefaultValue(propertyDescriptor),
|
||||
Editor = PropertyResolver.ResolveEditor(propertyDescriptor),
|
||||
Value = SelectedObject,
|
||||
PropertyName = propertyDescriptor.Name,
|
||||
PropertyType = propertyDescriptor.PropertyType,
|
||||
PropertyTypeName = $"{propertyDescriptor.PropertyType.Namespace}.{propertyDescriptor.PropertyType.Name}"
|
||||
};
|
||||
|
||||
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
|
||||
{
|
||||
base.OnRenderSizeChanged(sizeInfo);
|
||||
TitleElement.SetTitleWidth(this, new GridLength(Math.Max(MinTitleWidth, Math.Min(MaxTitleWidth, ActualWidth / 3))));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,136 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
public class PropertyItem : Control
|
||||
{
|
||||
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
|
||||
"Value", typeof(object), typeof(PropertyItem), new PropertyMetadata(default(object)));
|
||||
|
||||
public object Value
|
||||
{
|
||||
get => GetValue(ValueProperty);
|
||||
set => SetValue(ValueProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty DisplayNameProperty = DependencyProperty.Register(
|
||||
"DisplayName", typeof(string), typeof(PropertyItem), new PropertyMetadata(default(string)));
|
||||
|
||||
public string DisplayName
|
||||
{
|
||||
get => (string)GetValue(DisplayNameProperty);
|
||||
set => SetValue(DisplayNameProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty PropertyNameProperty = DependencyProperty.Register(
|
||||
"PropertyName", typeof(string), typeof(PropertyItem), new PropertyMetadata(default(string)));
|
||||
|
||||
public string PropertyName
|
||||
{
|
||||
get => (string)GetValue(PropertyNameProperty);
|
||||
set => SetValue(PropertyNameProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty PropertyTypeProperty = DependencyProperty.Register(
|
||||
"PropertyType", typeof(Type), typeof(PropertyItem), new PropertyMetadata(default(Type)));
|
||||
|
||||
public Type PropertyType
|
||||
{
|
||||
get => (Type) GetValue(PropertyTypeProperty);
|
||||
set => SetValue(PropertyTypeProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty PropertyTypeNameProperty = DependencyProperty.Register(
|
||||
"PropertyTypeName", typeof(string), typeof(PropertyItem), new PropertyMetadata(default(string)));
|
||||
|
||||
public string PropertyTypeName
|
||||
{
|
||||
get => (string)GetValue(PropertyTypeNameProperty);
|
||||
set => SetValue(PropertyTypeNameProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register(
|
||||
"Description", typeof(string), typeof(PropertyItem), new PropertyMetadata(default(string)));
|
||||
|
||||
public string Description
|
||||
{
|
||||
get => (string)GetValue(DescriptionProperty);
|
||||
set => SetValue(DescriptionProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register(
|
||||
"IsReadOnly", typeof(bool), typeof(PropertyItem), new PropertyMetadata(default(bool)));
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get => (bool)GetValue(IsReadOnlyProperty);
|
||||
set => SetValue(IsReadOnlyProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty DefaultValueProperty = DependencyProperty.Register(
|
||||
"DefaultValue", typeof(object), typeof(PropertyItem), new PropertyMetadata(default(object)));
|
||||
|
||||
public object DefaultValue
|
||||
{
|
||||
get => GetValue(DefaultValueProperty);
|
||||
set => SetValue(DefaultValueProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty CategoryProperty = DependencyProperty.Register(
|
||||
"Category", typeof(string), typeof(PropertyItem), new PropertyMetadata(default(string)));
|
||||
|
||||
public string Category
|
||||
{
|
||||
get => (string)GetValue(CategoryProperty);
|
||||
set => SetValue(CategoryProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty EditorProperty = DependencyProperty.Register(
|
||||
"Editor", typeof(PropertyEditorBase), typeof(PropertyItem), new PropertyMetadata(default(PropertyEditorBase)));
|
||||
|
||||
public PropertyEditorBase Editor
|
||||
{
|
||||
get => (PropertyEditorBase)GetValue(EditorProperty);
|
||||
set => SetValue(EditorProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty EditorElementProperty = DependencyProperty.Register(
|
||||
"EditorElement", typeof(FrameworkElement), typeof(PropertyItem), new PropertyMetadata(default(FrameworkElement)));
|
||||
|
||||
public FrameworkElement EditorElement
|
||||
{
|
||||
get => (FrameworkElement)GetValue(EditorElementProperty);
|
||||
set => SetValue(EditorElementProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register(
|
||||
"IsSelected", typeof(bool), typeof(PropertyItem), new PropertyMetadata(default(bool)));
|
||||
|
||||
public bool IsSelected
|
||||
{
|
||||
get => (bool)GetValue(IsSelectedProperty);
|
||||
set => SetValue(IsSelectedProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty IsExpandedEnabledProperty = DependencyProperty.Register(
|
||||
"IsExpandedEnabled", typeof(bool), typeof(PropertyItem), new PropertyMetadata(default(bool)));
|
||||
|
||||
public bool IsExpandedEnabled
|
||||
{
|
||||
get => (bool)GetValue(IsExpandedEnabledProperty);
|
||||
set => SetValue(IsExpandedEnabledProperty, value);
|
||||
}
|
||||
|
||||
public PropertyDescriptor PropertyDescriptor { get; set; }
|
||||
|
||||
public virtual void InitElement()
|
||||
{
|
||||
if (Editor == null) return;
|
||||
EditorElement = Editor.CreateElement(this);
|
||||
Editor.CreateBinding(this, EditorElement);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
public class PropertyItemsControl : ItemsControl
|
||||
{
|
||||
protected override bool IsItemItsOwnContainerOverride(object item) => item is PropertyItem;
|
||||
}
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using HandyControl.Properties.Langs;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
public class PropertyResolver
|
||||
{
|
||||
private static readonly Dictionary<Type, EditorTypeCode> TypeCodeDic = new Dictionary<Type, EditorTypeCode>
|
||||
{
|
||||
[typeof(string)] = EditorTypeCode.PlainText,
|
||||
[typeof(sbyte)] = EditorTypeCode.SByteNumber,
|
||||
[typeof(byte)] = EditorTypeCode.ByteNumber,
|
||||
[typeof(short)] = EditorTypeCode.Int16Number,
|
||||
[typeof(ushort)] = EditorTypeCode.UInt16Number,
|
||||
[typeof(int)] = EditorTypeCode.Int32Number,
|
||||
[typeof(uint)] = EditorTypeCode.UInt32Number,
|
||||
[typeof(long)] = EditorTypeCode.Int64Number,
|
||||
[typeof(ulong)] = EditorTypeCode.UInt64Number,
|
||||
[typeof(float)] = EditorTypeCode.SingleNumber,
|
||||
[typeof(double)] = EditorTypeCode.DoubleNumber,
|
||||
[typeof(bool)] = EditorTypeCode.Switch,
|
||||
[typeof(DateTime)] = EditorTypeCode.DateTime
|
||||
};
|
||||
|
||||
public string ResolveCategory(PropertyDescriptor propertyDescriptor)
|
||||
{
|
||||
var category = propertyDescriptor.Category;
|
||||
if (string.IsNullOrEmpty(category))
|
||||
{
|
||||
category = Lang.Miscellaneous;
|
||||
}
|
||||
|
||||
return category;
|
||||
}
|
||||
|
||||
public string ResolveDisplayName(PropertyDescriptor propertyDescriptor)
|
||||
{
|
||||
var displayName = propertyDescriptor.DisplayName;
|
||||
if (string.IsNullOrEmpty(displayName))
|
||||
{
|
||||
displayName = propertyDescriptor.Name;
|
||||
}
|
||||
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public string ResolveDescription(PropertyDescriptor propertyDescriptor) => propertyDescriptor.Description;
|
||||
|
||||
public bool ResolveIsBrowsable(PropertyDescriptor propertyDescriptor) => propertyDescriptor.IsBrowsable;
|
||||
|
||||
public bool ResolveIsDisplay(PropertyDescriptor propertyDescriptor) => propertyDescriptor.IsLocalizable;
|
||||
|
||||
public bool ResolveIsReadOnly(PropertyDescriptor propertyDescriptor) => propertyDescriptor.IsReadOnly;
|
||||
|
||||
public object ResolveDefaultValue(PropertyDescriptor propertyDescriptor)
|
||||
{
|
||||
var defaultValueAttribute = propertyDescriptor.Attributes.OfType<DefaultValueAttribute>().FirstOrDefault();
|
||||
return defaultValueAttribute?.Value;
|
||||
}
|
||||
|
||||
public PropertyEditorBase ResolveEditor(PropertyDescriptor propertyDescriptor)
|
||||
{
|
||||
var editorAttribute = propertyDescriptor.Attributes.OfType<EditorAttribute>().FirstOrDefault();
|
||||
var editor = editorAttribute == null || string.IsNullOrEmpty(editorAttribute.EditorTypeName)
|
||||
? CreateDefaultEditor(propertyDescriptor.PropertyType)
|
||||
: CreateEditor(Type.GetType(editorAttribute.EditorTypeName));
|
||||
|
||||
return editor;
|
||||
}
|
||||
|
||||
public virtual PropertyEditorBase CreateDefaultEditor(Type type) =>
|
||||
TypeCodeDic.TryGetValue(type, out var editorType)
|
||||
? editorType switch
|
||||
{
|
||||
EditorTypeCode.PlainText => new PlainTextPropertyEditor(),
|
||||
EditorTypeCode.SByteNumber => new NumberPropertyEditor(sbyte.MinValue, sbyte.MaxValue),
|
||||
EditorTypeCode.ByteNumber => new NumberPropertyEditor(byte.MinValue, byte.MaxValue),
|
||||
EditorTypeCode.Int16Number => new NumberPropertyEditor(short.MinValue, short.MaxValue),
|
||||
EditorTypeCode.UInt16Number => new NumberPropertyEditor(ushort.MinValue, ushort.MaxValue),
|
||||
EditorTypeCode.Int32Number => new NumberPropertyEditor(int.MinValue, int.MaxValue),
|
||||
EditorTypeCode.UInt32Number => new NumberPropertyEditor(uint.MinValue, uint.MaxValue),
|
||||
EditorTypeCode.Int64Number => new NumberPropertyEditor(long.MinValue, long.MaxValue),
|
||||
EditorTypeCode.UInt64Number => new NumberPropertyEditor(ulong.MinValue, ulong.MaxValue),
|
||||
EditorTypeCode.SingleNumber => new NumberPropertyEditor(float.MinValue, float.MaxValue),
|
||||
EditorTypeCode.DoubleNumber => new NumberPropertyEditor(double.MinValue, double.MaxValue),
|
||||
EditorTypeCode.Switch => new SwitchPropertyEditor(),
|
||||
EditorTypeCode.DateTime => new DateTimePropertyEditor(),
|
||||
_ => new ReadOnlyTextPropertyEditor()
|
||||
}
|
||||
: type.IsSubclassOf(typeof(Enum))
|
||||
? (PropertyEditorBase) new EnumPropertyEditor()
|
||||
: new ReadOnlyTextPropertyEditor();
|
||||
|
||||
public virtual PropertyEditorBase CreateEditor(Type type) => new ReadOnlyTextPropertyEditor();
|
||||
|
||||
private enum EditorTypeCode
|
||||
{
|
||||
PlainText,
|
||||
SByteNumber,
|
||||
ByteNumber,
|
||||
Int16Number,
|
||||
UInt16Number,
|
||||
Int32Number,
|
||||
UInt32Number,
|
||||
Int64Number,
|
||||
UInt64Number,
|
||||
SingleNumber,
|
||||
DoubleNumber,
|
||||
Switch,
|
||||
DateTime
|
||||
}
|
||||
}
|
||||
}
|
@ -40,6 +40,19 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Notification.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Poptip.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Watermark.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\PropertyGrid\Editors\EnumPropertyEditor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\PropertyGrid\Editors\ReadOnlyTextPropertyEditor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\PropertyGrid\Editors\TimePropertyEditor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\PropertyGrid\Editors\DatePropertyEditor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\PropertyGrid\Editors\SwitchPropertyEditor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\PropertyGrid\Editors\DateTimePropertyEditor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\PropertyGrid\Editors\PropertyEditorBase.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\PropertyGrid\Editors\NumberPropertyEditor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\PropertyGrid\Editors\PlainTextPropertyEditor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\PropertyGrid\PropertyGrid.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\PropertyGrid\PropertyItem.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\PropertyGrid\PropertyItemsControl.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\PropertyGrid\PropertyResolver.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Screenshot\Screenshot.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Sprite.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Block\ToggleBlock.cs" />
|
||||
@ -97,6 +110,7 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Tools\Converter\Double2GridLengthConverter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Tools\Converter\DoubleMinConverter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Tools\Converter\Number2PercentageConverter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Tools\Converter\Object2StringConverter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Tools\Converter\RectangleCircularConverter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Tools\Converter\ThicknessSplitConverter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Tools\Extension\DependencyObjectExtension.cs" />
|
||||
@ -419,6 +433,14 @@
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\PropertyGrid.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\Base\PropertyGridBaseStyle.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\Watermark.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
@ -171,5 +171,15 @@ namespace HandyControl.Interactivity
|
||||
/// 开始截图
|
||||
/// </summary>
|
||||
public static StartScreenshotCommand StartScreenshot { get; } = new StartScreenshotCommand();
|
||||
|
||||
/// <summary>
|
||||
/// 按照类别排序
|
||||
/// </summary>
|
||||
public static RoutedCommand SortByCategory { get; } = new RoutedCommand(nameof(SortByCategory), typeof(ControlCommands));
|
||||
|
||||
/// <summary>
|
||||
/// 按照名称排序
|
||||
/// </summary>
|
||||
public static RoutedCommand SortByName { get; } = new RoutedCommand(nameof(SortByName), typeof(ControlCommands));
|
||||
}
|
||||
}
|
@ -267,6 +267,17 @@ namespace HandyControl.Properties.Langs {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 杂项 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string Miscellaneous
|
||||
{
|
||||
get
|
||||
{
|
||||
return ResourceManager.GetString("Miscellaneous", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 下一页 的本地化字符串。
|
||||
/// </summary>
|
||||
|
@ -234,4 +234,7 @@
|
||||
<data name="Jump" xml:space="preserve">
|
||||
<value>Jump</value>
|
||||
</data>
|
||||
<data name="Miscellaneous" xml:space="preserve">
|
||||
<value>Miscellaneous</value>
|
||||
</data>
|
||||
</root>
|
@ -234,4 +234,7 @@
|
||||
<data name="Jump" xml:space="preserve">
|
||||
<value>Jump</value>
|
||||
</data>
|
||||
<data name="Miscellaneous" xml:space="preserve">
|
||||
<value>Miscellaneous</value>
|
||||
</data>
|
||||
</root>
|
@ -234,4 +234,7 @@
|
||||
<data name="Jump" xml:space="preserve">
|
||||
<value>Jump</value>
|
||||
</data>
|
||||
<data name="Miscellaneous" xml:space="preserve">
|
||||
<value>Miscellaneous</value>
|
||||
</data>
|
||||
</root>
|
@ -234,4 +234,7 @@
|
||||
<data name="Jump" xml:space="preserve">
|
||||
<value>Jump</value>
|
||||
</data>
|
||||
<data name="Miscellaneous" xml:space="preserve">
|
||||
<value>Miscellaneous</value>
|
||||
</data>
|
||||
</root>
|
@ -234,4 +234,7 @@
|
||||
<data name="Jump" xml:space="preserve">
|
||||
<value>跳转</value>
|
||||
</data>
|
||||
<data name="Miscellaneous" xml:space="preserve">
|
||||
<value>杂项</value>
|
||||
</data>
|
||||
</root>
|
@ -234,4 +234,7 @@
|
||||
<data name="Jump" xml:space="preserve">
|
||||
<value>Jump</value>
|
||||
</data>
|
||||
<data name="Miscellaneous" xml:space="preserve">
|
||||
<value>Miscellaneous</value>
|
||||
</data>
|
||||
</root>
|
@ -234,4 +234,7 @@
|
||||
<data name="Jump" xml:space="preserve">
|
||||
<value>Jump</value>
|
||||
</data>
|
||||
<data name="Miscellaneous" xml:space="preserve">
|
||||
<value>Miscellaneous</value>
|
||||
</data>
|
||||
</root>
|
@ -23,6 +23,7 @@
|
||||
<converter:ThicknessSplitConverter x:Key="ThicknessSplitConverter"/>
|
||||
<converter:CornerRadiusSplitConverter x:Key="CornerRadiusSplitConverter"/>
|
||||
<MenuScrollingVisibilityConverter x:Key="MenuScrollingVisibilityConverter"/>
|
||||
<converter:Double2GridLengthConverter x:Key="Double2GridLengthConverter" />
|
||||
<converter:DoubleMinConverter x:Key="DoubleMinConverter" />
|
||||
<converter:Double2GridLengthConverter x:Key="Double2GridLengthConverter"/>
|
||||
<converter:DoubleMinConverter x:Key="DoubleMinConverter"/>
|
||||
<converter:Object2StringConverter x:Key="Object2StringConverter"/>
|
||||
</ResourceDictionary>
|
@ -0,0 +1,159 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:o="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"
|
||||
xmlns:hc="clr-namespace:HandyControl.Controls"
|
||||
xmlns:themes="clr-namespace:HandyControl.Themes"
|
||||
xmlns:interactivity="clr-namespace:HandyControl.Interactivity">
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<themes:SharedResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Basic/Effects.xaml"/>
|
||||
<themes:SharedResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Styles/GroupBox.xaml"/>
|
||||
<themes:SharedResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Styles/SearchBar.xaml"/>
|
||||
<themes:SharedResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Styles/ButtonGroup.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<DrawingBrush x:Key="SortByCategoryDrawingBrush" o:Freeze="True">
|
||||
<DrawingBrush.Drawing>
|
||||
<DrawingGroup o:Freeze="True">
|
||||
<GeometryDrawing o:Freeze="True" Brush="#00FFFFFF" Geometry="F1M16,16L0,16 0,0 16,0z" />
|
||||
<GeometryDrawing o:Freeze="True" Brush="#FFF6F6F6" Geometry="F1M0.9999,-0.000199999999999534L0.9999,15.9998 10.9999,15.9998 10.9999,13.4148 11.9999,14.4138 15.9999,10.4138 15.9999,5.5858 14.0009,7.5858 14.0009,3.0008 10.9999,3.0008 10.9999,-0.000199999999999534z" />
|
||||
<GeometryDrawing o:Freeze="True" Brush="#FF424242" Geometry="F1M10,12.4141L10,15.0001 2,15.0001 2,1.0001 10,1.0001 10,3.0001 10,7.5861 8.414,6.0001 9,6.0001 9,3.0001 3,3.0001 3,6.0001 8,6.0001 8,7.0001 3,7.0001 3,10.0001 8,10.0001 8,10.4141 8.586,11.0001 3,11.0001 3,14.0001 9,14.0001 9,11.4141z" />
|
||||
<GeometryDrawing o:Freeze="True" Brush="#FFEFEFF0" Geometry="F1M8.5859,11L2.9999,11 2.9999,14 8.9999,14 8.9999,11.414z M7.9999,7L2.9999,7 2.9999,10 7.9999,10z M7.9999,6L2.9999,6 2.9999,3 8.9999,3 8.9999,6 8.4139,6 7.9999,5.586z" />
|
||||
<GeometryDrawing o:Freeze="True" Brush="#FF00529C" Geometry="F1M13,10L13,4 11,4 11,10 9,8 9,10 12,13 15,10 15,8z" />
|
||||
</DrawingGroup>
|
||||
</DrawingBrush.Drawing>
|
||||
</DrawingBrush>
|
||||
|
||||
<DrawingBrush x:Key="SortByNameDrawingBrush" o:Freeze="True">
|
||||
<DrawingBrush.Drawing>
|
||||
<DrawingGroup o:Freeze="True">
|
||||
<GeometryDrawing o:Freeze="True" Brush="#00FFFFFF" Geometry="F1M16,16L0,16 0,0 16,0z" />
|
||||
<GeometryDrawing o:Freeze="True" Brush="#FFF6F6F6" Geometry="F1M0,-0.000199999999999534L0,8.9998 1,8.9998 1,12.0008 2.586,12.0008 1,13.5858 1,15.9998 8,15.9998 8,13.0008 6.449,13.0008 8,12.0008 8,10.9998 12,14.9998 16,10.9998 16,4.9998 14,6.9998 14,3.0008 10,3.0008 10,6.9998 9,5.9998 9,-0.000199999999999534z" />
|
||||
<GeometryDrawing o:Freeze="True" Brush="#FF424242" Geometry="F1M7,7L5,2 4,2 2,7 3,7 3.399,6 5.601,6 6,7z M8,8L1,8 1,1 8,1z M4.5,3.25L5.2,5 3.8,5z M2,11L5,11 2,14 2,15 7,15 7,14 4.013,14 7,11.051 6.952,11 7,11 7,10 2,10z" />
|
||||
<GeometryDrawing o:Freeze="True" Brush="#FFEFEFF0" Geometry="F1M3.7998,5L4.4998,3.25 5.1998,5z M5.9998,7L6.9998,7 4.9998,2 3.9998,2 1.9998,7 2.9998,7 3.3998,6 5.6008,6z" />
|
||||
<GeometryDrawing o:Freeze="True" Brush="#FF00529C" Geometry="F1M15,8L15,10 12,13 9,10 9,8 11,10 11,4 13,4 13,10z" />
|
||||
</DrawingGroup>
|
||||
</DrawingBrush.Drawing>
|
||||
</DrawingBrush>
|
||||
|
||||
<Style x:Key="PropertyItemToolTipBaseStyle" BasedOn="{StaticResource {x:Type ToolTip}}" TargetType="ToolTip">
|
||||
<Setter Property="Padding" Value="10"/>
|
||||
<Setter Property="hc:BorderElement.CornerRadius" Value="2"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ToolTip">
|
||||
<Border Effect="{StaticResource EffectShadow2}" Margin="8" Background="{DynamicResource RegionBrush}" Padding="{TemplateBinding Padding}" BorderThickness="1" CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" BorderBrush="{DynamicResource BorderBrush}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<ContentPresenter x:Name="Presenter" Margin="0,0,0,10"/>
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal">
|
||||
<TextBlock FontWeight="Bold" Text="{Binding PropertyTypeName,RelativeSource={RelativeSource AncestorType=hc:PropertyItem}}"/>
|
||||
<TextBlock Text="{Binding PropertyName,RelativeSource={RelativeSource AncestorType=hc:PropertyItem}}" Margin="6,0,0,0"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="Content" Value="{x:Null}">
|
||||
<Setter TargetName="Presenter" Property="Visibility" Value="Collapsed"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Content" Value="">
|
||||
<Setter TargetName="Presenter" Property="Visibility" Value="Collapsed"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PropertyItemBaseStyle" TargetType="hc:PropertyItem">
|
||||
<Setter Property="Focusable" Value="False"/>
|
||||
<Setter Property="Margin" Value="0,0,0,6"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="hc:PropertyItem">
|
||||
<GroupBox Style="{StaticResource GroupBoxOriginal}" hc:TitleElement.TitlePlacement="Left">
|
||||
<GroupBox.Header>
|
||||
<TextBlock Padding="0,0,10,0" Width="{Binding Path=(hc:TitleElement.TitleWidth).Value,RelativeSource={RelativeSource TemplatedParent}}" Text="{TemplateBinding DisplayName}" TextTrimming="CharacterEllipsis">
|
||||
<TextBlock.ToolTip>
|
||||
<ToolTip Style="{StaticResource PropertyItemToolTipBaseStyle}" Content="{TemplateBinding Description}"/>
|
||||
</TextBlock.ToolTip>
|
||||
</TextBlock>
|
||||
</GroupBox.Header>
|
||||
<ContentPresenter ContentSource="EditorElement"/>
|
||||
</GroupBox>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PropertyGroupItemBaseStyle" TargetType="GroupItem">
|
||||
<Setter Property="Margin" Value="0,0,0,6"/>
|
||||
<Setter Property="Padding" Value="10,6,6,0"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="GroupItem">
|
||||
<Expander BorderThickness="1" BorderBrush="{DynamicResource BorderBrush}" Header="{Binding Name}" IsExpanded="True" Background="{DynamicResource SecondaryRegionBrush}" Foreground="{DynamicResource PrimaryTextBrush}">
|
||||
<Border BorderThickness="1,0,1,1" BorderBrush="{DynamicResource BorderBrush}" Background="{DynamicResource RegionBrush}" CornerRadius="0,0,4,4">
|
||||
<ItemsPresenter Margin="{TemplateBinding Padding}"/>
|
||||
</Border>
|
||||
</Expander>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<ItemsPanelTemplate x:Key="PropertyItemsControlItemsPanelTemplate">
|
||||
<VirtualizingStackPanel FocusVisualStyle="{x:Null}" VirtualizationMode="Recycling"/>
|
||||
</ItemsPanelTemplate>
|
||||
|
||||
<Style x:Key="PropertyItemsControlBaseStyle" TargetType="hc:PropertyItemsControl">
|
||||
<Setter Property="ItemContainerStyle" Value="{StaticResource PropertyItemBaseStyle}"/>
|
||||
<Setter Property="ItemsPanel" Value="{StaticResource PropertyItemsControlItemsPanelTemplate}"/>
|
||||
<Setter Property="Focusable" Value="False"/>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="hc:PropertyGrid">
|
||||
<Setter Property="MaxTitleWidth" Value="200"/>
|
||||
<Setter Property="MinTitleWidth" Value="120"/>
|
||||
<Setter Property="Focusable" Value="False"/>
|
||||
<Setter Property="Padding" Value="10"/>
|
||||
<Setter Property="Background" Value="{DynamicResource RegionBrush}"/>
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="hc:PropertyGrid">
|
||||
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
|
||||
<Grid Margin="{TemplateBinding Padding}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<DockPanel LastChildFill="True" Margin="0,0,0,6">
|
||||
<hc:ButtonGroup Style="{StaticResource ButtonGroupSolid}">
|
||||
<RadioButton Command="interactivity:ControlCommands.SortByCategory" IsChecked="True">
|
||||
<Rectangle Width="16" Height="16" Fill="{StaticResource SortByCategoryDrawingBrush}"/>
|
||||
</RadioButton>
|
||||
<RadioButton Command="interactivity:ControlCommands.SortByName">
|
||||
<Rectangle Width="16" Height="16" Fill="{StaticResource SortByNameDrawingBrush}"/>
|
||||
</RadioButton>
|
||||
</hc:ButtonGroup>
|
||||
<hc:SearchBar x:Name="PART_SearchBar" IsRealTime="True" Margin="6,0,0,0" ShowClearButton="True" Style="{StaticResource SearchBarPlus}"/>
|
||||
</DockPanel>
|
||||
<ScrollViewer Grid.Row="1">
|
||||
<hc:PropertyItemsControl x:Name="PART_ItemsControl" Style="{StaticResource PropertyItemsControlBaseStyle}">
|
||||
<hc:PropertyItemsControl.GroupStyle>
|
||||
<GroupStyle ContainerStyle="{StaticResource PropertyGroupItemBaseStyle}"/>
|
||||
</hc:PropertyItemsControl.GroupStyle>
|
||||
</hc:PropertyItemsControl>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
@ -1,6 +1,11 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:HandyControl.Controls">
|
||||
xmlns:controls="clr-namespace:HandyControl.Controls"
|
||||
xmlns:themes="clr-namespace:HandyControl.Themes">
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<themes:SharedResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Basic/Effects.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<Style x:Key="ToolTipBaseStyle" TargetType="ToolTip">
|
||||
<Setter Property="Padding" Value="0,6"/>
|
||||
@ -11,7 +16,7 @@
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ToolTip">
|
||||
<Border Background="{DynamicResource RegionBrush}" Padding="{TemplateBinding Padding}" BorderThickness="1" CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" BorderBrush="{DynamicResource BorderBrush}">
|
||||
<Border Effect="{StaticResource EffectShadow2}" Margin="8" Background="{DynamicResource RegionBrush}" Padding="{TemplateBinding Padding}" BorderThickness="1" CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" BorderBrush="{DynamicResource BorderBrush}">
|
||||
<ContentPresenter Margin="10,0"/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
|
@ -0,0 +1,11 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:controls="clr-namespace:HandyControl.Controls"
|
||||
xmlns:themes="clr-namespace:HandyControl.Themes">
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<themes:SharedResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Styles/Base/PropertyGridBaseStyle.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<Style BasedOn="{StaticResource PropertyGridBaseStyle}" TargetType="controls:Badge"/>
|
||||
|
||||
</ResourceDictionary>
|
@ -88,6 +88,7 @@
|
||||
<themes:SharedResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Styles/BlendEffectBox.xaml"/>
|
||||
<themes:SharedResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Styles/Screenshot.xaml"/>
|
||||
<themes:SharedResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Styles/Watermark.xaml"/>
|
||||
<themes:SharedResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Styles/PropertyGrid.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
</ResourceDictionary>
|
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace HandyControl.Tools.Converter
|
||||
{
|
||||
public class Object2StringConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) => value?.ToString();
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user