我有一个 Avalonia 模板控件,其样式属性为“Value”,它是一个字符串。 它的目的是接受一系列由空格分隔的标签。 我想拆分该字符串并在项目控件(或项目重复器)中显示各个标签。
所以 - 我编写了代码来捕获“值”的更改,并将这些值拆分出来并将它们放入可观察的集合中。 我知道该集合已正确填充,但我无法让它显示在控件上。
我尝试过将集合作为可观察集合、avalonialist、样式属性、直接属性等。还尝试了模板绑定与绑定到项目控件的父级。
对我做错了什么有什么想法吗?
public class FormTagControl : TemplatedControl
{
public static readonly StyledProperty<string> ValueProperty =
AvaloniaProperty.Register<FormTagControl, string>(nameof(Value), defaultBindingMode: BindingMode.TwoWay);
public static readonly StyledProperty<bool> ShowEditModeProperty =
AvaloniaProperty.Register<FormTagControl, bool>(nameof(ShowEditMode), defaultBindingMode: BindingMode.TwoWay);
public static readonly StyledProperty<bool> ShowAddButtonProperty =
AvaloniaProperty.Register<FormTagControl, bool>(nameof(ShowEditMode), defaultBindingMode: BindingMode.TwoWay);
public static readonly StyledProperty<string> ErrorMessageProperty =
AvaloniaProperty.Register<FormTagControl, string>(nameof(ErrorMessage), defaultBindingMode: BindingMode.OneWay);
public static readonly StyledProperty<string> LabelProperty =
AvaloniaProperty.Register<FormTagControl, string>(nameof(Label), defaultBindingMode: BindingMode.OneWay);
public static readonly StyledProperty<string> WatermarkProperty =
AvaloniaProperty.Register<FormTagControl, string>(nameof(Watermark), defaultBindingMode: BindingMode.OneWay);
public ObservableCollection<string> Tags { get; set; } = new();
protected bool ShowEditMode
{
get => GetValue(ShowEditModeProperty);
set => SetValue(ShowEditModeProperty, value);
}
protected bool ShowAddButton
{
get => GetValue(ShowAddButtonProperty);
set => SetValue(ShowAddButtonProperty, value);
}
public string Value
{
get => GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
public string ErrorMessage
{
get => GetValue(ErrorMessageProperty);
set => SetValue(ErrorMessageProperty, value);
}
public string Label
{
get => GetValue(LabelProperty);
set => SetValue(LabelProperty, value);
}
public string Watermark
{
get => GetValue(WatermarkProperty);
set => SetValue(WatermarkProperty, value);
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
var btnGoToEditMode = e.NameScope.Find<Button>("PART_GoToEditModeButton");
var btnGoToViewMode = e.NameScope.Find<Button>("PART_GoToViewModeButton");
var btnAddTags = e.NameScope.Find<Button>("PART_AddButton");
if (btnGoToEditMode is not null)
{
btnGoToEditMode.Click += (s, e) =>
{
ShowEditMode = true;
};
}
if (btnGoToViewMode is not null)
{
btnGoToViewMode.Click += (s, e) =>
{
ShowEditMode = false;
};
}
if (btnAddTags is not null)
{
btnAddTags.Click += (s, e) =>
{
ShowEditMode = true;
};
}
base.OnApplyTemplate(e);
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
if (change.Property.Name == nameof(Value))
{
if (string.IsNullOrEmpty(change.NewValue?.ToString()))
{
ShowAddButton = true;
}
else
{
ShowAddButton = false;
}
BuildTagList();
}
base.OnPropertyChanged(change);
}
protected void BuildTagList()
{
Tags.Clear();
string[] tagValues = Value.Split(' ', StringSplitOptions.RemoveEmptyEntries);
foreach (string tagValue in tagValues)
{
Tags.Add(tagValue);
}
}
}
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="https://github.com/projektanker/icons.avalonia"
xmlns:controls="using:NRS.UI.Mvvm.FormControls">
<Design.PreviewWith>
<controls:FormTagControl />
</Design.PreviewWith>
<Style Selector="controls|FormTagControl">
<!-- Set Defaults -->
<Setter Property="Template">
<ControlTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Classes="NRSLabel" Text="{TemplateBinding Label}"></TextBlock>
<Grid Grid.Row="1" IsVisible="{TemplateBinding ShowEditMode}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button i:Attached.Icon="fa-solid fa-grip" Grid.Column="0" Name="PART_GoToViewModeButton" Classes="NoStyling" Height="38">
</Button>
<TextBox Grid.Column="1" Watermark="{TemplateBinding Watermark}"
Text="{Binding Value, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"/>
</Grid>
<Grid Grid.Row="1" IsVisible="{TemplateBinding ShowEditMode,Converter={x:Static BoolConverters.Not}}">
<Button Name="PART_GoToEditModeButton" Classes="NoStyling" Height="38"
IsVisible="{TemplateBinding ShowAddButton,Converter={x:Static BoolConverters.Not}}">
<ItemsControl Margin="0 40 0 0" ItemsSource="{Binding Tags, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Button>
<Button Name="PART_AddButton" Height="38"
IsVisible="{TemplateBinding ShowAddButton}">
<Label>Add Tags</Label>
</Button>
</Grid>
<TextBlock Grid.Row="2" Classes="NRSErrorMessage" Text="{TemplateBinding ErrorMessage}" />
</Grid>
</ControlTemplate>
</Setter>
</Style>
</Styles>
我用正确的答案更新了问题