在模板化控件上显示可观察集合

问题描述 投票:0回答:1

我有一个 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>
avaloniaui
1个回答
0
投票

我用正确的答案更新了问题

© www.soinside.com 2019 - 2024. All rights reserved.