SegmentedEditor
SegmentedEditor
представляет набор элементов (опций) в виде горизонтально расположенных сегментов. Пользователь может щелкнуть по одному из сегментов, чтобы выбрать соответствующую опцию, или нажать CTRL на выбранном сегменте, чтобы отменить выделение.
Основные функции контрола включают в себя:
- Заполнение сегментов из списка строк, списка бизнес-объектов или из тип-перечисления.
- Шаблоны элементов позволяют отображать сегменты произвольным способом.
- Использование контрола в качестве встроенного редактора в контролах-контейнерах (например, TreeList, TreeView и PropertyGrid).
Источник объектов
Используйте свойство SegmentedEditor.ItemsSource
, чтобы указать источник объектов, используемый для создания сегментов контрола. Вы можете привязать редактор к списку строк, списку бизнес-объектов или к типу-перечислению.
Привязка к списку строк
Самый простой источник объектов - это список строк.
Пример - Как привязать к списку строк
В следующем примере контрол SegmentedEditor
заполняется списком строк.
xmlns:mxe="using:Eremex.AvaloniaUI.Controls.Editors"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:col="using:System.Collections"
<mxe:SegmentedEditor>
<mxe:SegmentedEditor.ItemsSource>
<col:ArrayList>
<sys:String>Montevideo</sys:String>
<sys:String>Havana</sys:String>
<sys:String>Santiago</sys:String>
<sys:String>La Paz</sys:String>
</col:ArrayList>
</mxe:SegmentedEditor.ItemsSource>
</mxe:SegmentedEditor>
Привязка к списку бизнес-объектов
Вы можете привязать контрол SegmentedEditor
к списку бизнес-объектов. В этом случае дефолтное поведение контрола является следующим:
- Метод
ToString
бизнес-объекта задает дефолтное представление текста элементов. - Когда вы выбираете элемент, значение редактора (
SegmentedEditor.EditorValue
) устанавливается равным соответствующему бизнес-объекту.
Типичный бизнес-объект обладает множеством свойств. Вы можете указать, какие свойства бизнес-объекта предоставляют текст элемента для отображения и редактирования значений. Для этой цели используйте следующие элементы API:
SegmentedEditor.DisplayMember
- Получает или задает имя свойства бизнес-объекта, которое определяет текст элемента для отображения.SegmentedEditor.ValueMember
- Получает или задает имя свойства бизнес-объекта, которое определяет значения элемента. Когда вы выбираете элемент, значение редактора (SegmentedEditor.EditorValue
) устанавливается равным значению свойстваValueMember
элемента.
Пример - Как привязать к списку бизнес-объектов
Следующий пример привязывает контрол SegmentedEditor к списку бизнес-объектов Product. Свойство Product.ProductName определяет текст элемента для отображения. Свойство Product.ProductID определяет значения элементов.
xmlns:mxe="using:Eremex.AvaloniaUI.Controls.Editors"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<mxe:SegmentedEditor
Name="segmEditor1"
ItemsSource="{Binding Products}"
DisplayMember="ProductName"
ValueMember="ProductID" />
public MainViewModel()
{
Products = new ObservableCollection<Product>();
Products.Add(new Product(0, "Chai", "Beverages", 200));
Products.Add(new Product(1, "Chang", "Beverages", 100))
Products.Add(new Product(3, "Ikura", "Seafood", 500));
Products.Add(new Product(5, "Tofu", "Produce", 430));
//...
}
public partial class Product :ObservableObject
{
public Product(int productID, string productName, string category, int productPrice)
{
ProductID = productID;
ProductName = productName;
Category = category;
ProductPrice = productPrice;
}
[ObservableProperty]
public int productID;
[ObservableProperty]
public string productName;
[ObservableProperty]
public string category;
[ObservableProperty]
public decimal productPrice;
}
Привязка к перечислению
SegmentedEditor
может заполнять свои сегменты значениями с тип-перечислением.
Вспомогательный класс Eremex.AvaloniaUI.Controls.Common.EnumItemsSource
облегчает привязку к перечислению. Его основные функции включают:
- Картинки для элементов перечисления. Примените атрибут
Eremex.AvaloniaUI.Controls.Common.ImageAttribute
к целевым элементам перечисления, чтобы указать картинки. - Пользовательские отображаемые имена для элементов перечисления. Используйте атрибут
System.ComponentModel.DataAnnotations.DisplayAttribute
или пользовательский конвертер, чтобы изменить дефолтный отображаемый текст элемента. - Всплывающие подсказки для элементов. Всплывающая подсказка содержит описание целевого элемента, которое вы можете предоставить с помощью атрибута
System.ComponentModel.DataAnnotations.DisplayAttribute
или пользовательского конвертера.
Чтобы настроить привязку к типу-перечислению, используйте следующие свойства EnumItemsSource
:
EnumItemsSource.EnumType
— Задает тип-перечисление, значения которого отображаются в контролеSegmentedEditor
.EnumItemsSource.ShowImages
— Указывает, следует ли отображать картинки для элементов перечисления. Вы можете предоставить картинки, используя атрибутEremex.AvaloniaUI.Controls.Common.ImageAttribute
.EnumItemsSource.ShowNames
— Указывает, следует ли отображать текст элемента. Установите дляShowNames
значениеfalse
, а дляShowImages
значениеtrue
, чтобы отображать элементы перечисления с использованием картинок без текста.EnumItemsSource.ImageSize
— Определяет размер отображения картинок, назначенных элементам перечисления.EnumItemsSource.NameToDisplayTextConverter
— Позволяет назначить конвертер, который извлекает пользовательский текст для отображения для элементов перечисления.EnumItemsSource.NameToDescriptionConverter
— Позволяет назначить конвертер, который извлекает описания элементов перечисления, которые отображаются в виде всплывающих подсказок, когда пользователь наводит курсор мыши на сегменты.
Пример - Как отобразить значения перечисления и использовать атрибуты для предоставления текста и картинок для элементов перечисления.
В следующем примере отображаются значения перечисления ProductCategoryEnum в SegmentedEditor
. В нем используется класс EnumItemsSource
для привязки данных.
Атрибуты System.ComponentModel.DataAnnotations.DisplayAttribute
и Eremex.AvaloniaUI.Controls.Common.ImageAttribute
определяют пользовательский текст для отображения, описания (всплывающие подсказки) и картинки для элементов перечисления.
xmlns:mxcom="clr-namespace:Eremex.AvaloniaUI.Controls.Common;assembly=Eremex.Avalonia.Controls"
xmlns:mxe="using:Eremex.AvaloniaUI.Controls.Editors"
<mxe:SegmentedEditor Name="segmentedEditorEnum"
ItemsSource="{mxcom:EnumItemsSource EnumType=local:ProductCategoryEnum, ImageSize='16, 16', ShowImages=True, ShowNames=True}"
>
</mxe:SegmentedEditor>
using Eremex.AvaloniaUI.Controls.Common;
using System.ComponentModel.DataAnnotations;
public enum ProductCategoryEnum
{
// The images assigned to the enumeration values below are placed in the EditorsSample/Images folder.
// They have their "Build Action" properties set to "AvaloniaResource".
[Image($"avares://EditorsSample/Images/Products/DairyProducts.svg")]
[Display(Name = "Dairy Products", Description = "Products made from milk")]
DairyProducts,
[Image($"avares://EditorsSample/Images/Products/Beverages.svg")]
[Display(Description = "Edible drinks")]
Beverages,
[Image($"avares://EditorsSample/Images/Products/Condiments.svg")]
[Display(Description = "Flavor Enhancers")]
Condiments,
[Image($"avares://EditorsSample/Images/Products/Confections.svg")]
[Display(Description = "Sweets")]
Confections
}
Пример - Как отобразить значения перечисления и использовать пользовательские конвертеры для предоставления текста для элементов перечисления.
В следующем примере для отображения значений типа-перечисления в контроле SegmentedEditor
используется класс EnumItemsSource
. Объекты EnumItemsSource.NameToDisplayTextConverter
и EnumItemsSource.NameToDescriptionConverter
предоставляют пользовательский текст для отображения и описания (всплывающие подсказки) для элементов перечисления.
xmlns:mxe="using:Eremex.AvaloniaUI.Controls.Editors"
xmlns:mxcom="clr-namespace:Eremex.AvaloniaUI.Controls.Common;assembly=Eremex.Avalonia.Controls"
xmlns:local="clr-namespace:EditorsSample"
<mxe:SegmentedEditor Name="segmentedEditorEnumWithConverters"
ItemsSource="{mxcom:EnumItemsSource EnumType=local:ProductCategoryEnum, ImageSize='16, 16', ShowImages=True, ShowNames=True, NameToDisplayTextConverter={local:EnumMemberNameToDisplayTextConverter}, NameToDescriptionConverter={local:EnumMemberNameToDescriptionConverter}}"
>
</mxe:SegmentedEditor>
using Eremex.AvaloniaUI.Controls.Common;
public enum ProductCategoryEnum
{
// The images assigned to the enumeration values below are placed in the EditorsSample/Images folder.
// They have their "Build Action" properties set to "AvaloniaResource".
[Image($"avares://EditorsSample/Images/Products/DairyProducts.svg")]
DairyProducts,
[Image($"avares://EditorsSample/Images/Products/Beverages.svg")]
Beverages,
[Image($"avares://EditorsSample/Images/Products/Condiments.svg")]
Condiments,
[Image($"avares://EditorsSample/Images/Products/Confections.svg")]
Confections
}
public class EnumMemberNameToDisplayTextConverter : BaseEnumConverter
{
protected override void PopulateDictionary()
{
TextValueDictionary.Add("ProductCategoryEnum_DairyProducts", "Dairy");
}
}
public class EnumMemberNameToDescriptionConverter : BaseEnumConverter
{
protected override void PopulateDictionary()
{
TextValueDictionary.Add("ProductCategoryEnum_DairyProducts", "Milk Products");
}
}
public abstract class BaseEnumConverter : MarkupExtension, IValueConverter
{
protected Dictionary<string, string> TextValueDictionary;
public BaseEnumConverter()
{
TextValueDictionary = new Dictionary<string, string>();
PopulateDictionary();
}
protected abstract void PopulateDictionary();
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
public object? Convert(object? value, Type targetType, object? parameter, System.Globalization.CultureInfo culture)
{
var type = value?.GetType();
var memberName = value?.ToString();
if (type == null || !type.IsEnum || string.IsNullOrEmpty(memberName))
return null;
return EnumMemberToString(type.Name, memberName);
}
protected virtual string EnumMemberToString(string enumName, string enumMemberName)
{
string fullMemberName = enumName + "_" + enumMemberName;
if (TextValueDictionary.ContainsKey(fullMemberName))
return TextValueDictionary[fullMemberName];
else
return enumMemberName;
}
public object? ConvertBack(object? value, Type targetType, object? parameter, System.Globalization.CultureInfo culture)
{
return null;
}
}
Получение и установка выбранного элемента, а также выставление значения редактора
Когда пользователь выбирает сегмент или отменяет его выбор щелчком мыши с Ctrl, свойства SegmentedEditor.SelectedItem
и SegmentedEditor.EditorValue
изменяются соответствующим образом.
Вы можете использовать любое из этих свойств, чтобы получить и установить выбранное значение редактора.
Свойство SegmentedEditor.SelectedItem
определяет нижележащий объект данных выбранного сегмента.
Свойство SegmentedEditor.EditorValue
имеет следующие значения:
- Если свойство
ValueMember
пусто, то свойстваEditorValue
иSelectedItem
эквивалентны. - В противном случае свойство
EditorValue
синхронизируется со значением свойстваValueMember
выбранного нижележащего объекта данных.
Чтобы снять выделение, установите для свойства SegmentedEditor.SelectedItem
значение null
.
Пример - Как выбрать элемент, когда SegmentedEditor привязан к списку строк
В следующем примере показано, как использовать свойство SelectedItem
или EditorValue
для выбора элемента в контроле SegmentedEditor
, который привязан к списку строк.
xmlns:mxe="using:Eremex.AvaloniaUI.Controls.Editors"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:col="using:System.Collections"
<mxe:SegmentedEditor Name="segmEditorStrings">
<mxe:SegmentedEditor.ItemsSource>
<col:ArrayList>
<sys:String>Montevideo</sys:String>
<sys:String>Havana</sys:String>
<sys:String>Santiago</sys:String>
<sys:String>La Paz</sys:String>
</col:ArrayList>
</mxe:SegmentedEditor.ItemsSource>
</mxe:SegmentedEditor>
// Use the SelectedItem property:
segmEditorStrings.SelectedItem = "Santiago";
//or the EditorValue property:
segmEditorStrings.EditorValue = "Santiago";
Пример - Как выбрать элемент, когда SegmentedEditor привязан к списку бизнес-объектов
В следующем примере контрол SegmentedEditor
привязан к списку объектов Product. Свойство ValueMember
ссылается на элемент Product.ProductID. Таким образом, идентификаторы продуктов служат значениями элементов. Когда пользователь выбирает сегмент, свойству EditorValue
присваивается соответствующий идентификатор продукта. В примере используется свойство EditorValue
для выбора элемента в коде.
xmlns:mxe="using:Eremex.AvaloniaUI.Controls.Editors"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:EditorsSample"
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<mxe:SegmentedEditor
Name="segmEditor1"
ItemsSource="{Binding Products}"
DisplayMember="ProductName"
ValueMember="ProductID" />
// Select an item by its product ID:
var itemSource = segmEditor1.ItemsSource as ObservableCollection<Product>;
if (itemSource != null)
segmEditor1.EditorValue = itemSource[3].ProductID;
//The SelectedItem property will return the itemSource[3] object.
//...
[ObservableObject]
public partial class MainViewModel : ViewModelBase
{
[ObservableProperty]
public ObservableCollection<Product> products;
public MainViewModel()
{
Products = new ObservableCollection<Product>();
Products.Add(new Product(0, "Chai", "Beverages", 200));
Products.Add(new Product(1, "Chang", "Beverages", 100))
Products.Add(new Product(3, "Ikura", "Seafood", 500));
Products.Add(new Product(5, "Tofu", "Produce", 430));
}
}
public partial class Product :ObservableObject
{
public Product(int productID, string productName, string category, int productPrice)
{
ProductID = productID;
ProductName = productName;
Category = category;
ProductPrice = productPrice;
}
[ObservableProperty]
public int productID;
[ObservableProperty]
public string productName;
[ObservableProperty]
public string category;
[ObservableProperty]
public decimal productPrice;
}
Шаблоны элементов
Когда SegmentedEditor
привязан к списку строк или бизнес-объектов, сегменты контрола отображают дефолтное представление текста элементов. Дефолтный отображаемый текст элемента определяется следующим образом:
- Значение, возвращаемое методом
ToString
нижележащего объекта данных, если свойствоValueMember
не задано. - В противном случае используется текстовое представление значения, хранящегося в свойстве
ValueMember
объекта данных.
Шаблоны элементов дают вам возможность гибко указывать, что отображать в сегментах редактора. Они позволяют отображать картинки и значения нескольких свойств в сегментах. Используйте свойство SegmentedEditor.ItemTemplate
, чтобы указать шаблон элемента.
Пример - Как отобразить картинку и текст для элементов SegmentedEditor
В следующем примере показано, как создать шаблон элемента, который отображает картинки и текст в сегментах контрола SegmentedEditor
.
В примере контрол SegmentedEditor
привязан к коллекции объектов CapitalInfo, которые хранят информацию о странах, столицах стран и национальных флагах.
Созданный шаблон элемента (свойство SegmentedEditor.ItemTemplate
) отображает флаг страны, за которым следует название столицы страны.
Свойство SegmentedEditor.ValueMember
ссылается на свойство CapitalInfo.Capital. Когда пользователь выбирает сегмент, свойству редактора EditorValue
присваивается название столицы соответствующей страны.
xmlns:mxe="using:Eremex.AvaloniaUI.Controls.Editors"
xmlns:local="clr-namespace:EditorsSample"
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Window.Resources>
<DataTemplate x:Key="CapitalItemTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Width="16" Height="16" Source="{Binding Path=Flag}"/>
<TextBlock VerticalAlignment="Center" Grid.Column="1" Margin="6,0,0,0" Text="{Binding Path=Capital}"/>
</Grid>
</DataTemplate>
</Window.Resources>
<mxe:SegmentedEditor
Name="segmentedEditorCapitals"
ItemsSource="{Binding Capitals}"
ItemTemplate="{StaticResource CapitalItemTemplate}"
ValueMember="Capital"
/>
using CommunityToolkit.Mvvm.ComponentModel;
using Avalonia.Media;
using Avalonia.Svg.Skia;
public partial class MainViewModel
{
[ObservableProperty]
public ObservableCollection<CapitalInfo> capitals;
public MainViewModel()
{
var capitalDictionary = new List<(string capital, string country)>();
capitalDictionary.Add(("Havana", "Cuba"));
capitalDictionary.Add(("Santiago", "Chile"));
capitalDictionary.Add(("La Paz", "Bolivia"));
Capitals = new ObservableCollection<CapitalInfo>();
foreach (var item in capitalDictionary)
{
string country = item.country.ToLower();
// Load .SVG images that are stored in the Images/Flags folder as Avalonia Resources.
IImage image = SvgImageExtension.ProvideValue($"avares://EditorsSample/Images/Flags/{country}.svg", null!, null!);
Capitals.Add(new CapitalInfo(item.capital, item.country, image));
}
}
}
public partial class CapitalInfo : ObservableObject
{
public CapitalInfo(string capital, string country, IImage flag)
{
Capital = capital;
Flag = flag;
Country = country;
}
[ObservableProperty]
public string capital;
[ObservableProperty]
public string country;
[ObservableProperty]
public IImage flag;
}
* Эта страница была создана автоматически с помощью сервиса машинного перевода Яндекс Переводчик.