Я пытаюсь реализовать пользовательский элемент управления, который представляет собой временную шкалу (например, в видеоредакторе) с сегментом, начальный и конечный маркеры которого может перетаскивать пользователь.
Я представляю такой сегмент в моей модели представления:
public class Moment : ViewModelBase
{
[Reactive] public double From { get; set; }
[Reactive] public double Duration { get; set; }
}
И попытался реализовать представление, используя сетку с разделителями сетки следующим образом:
<Grid ColumnDefinitions="Auto,3,Auto,3,*" HorizontalAlignment="Stretch">
<Panel Grid.Column="0" Name="SpacerLeft"
Width="{Binding From}" />
<GridSplitter Grid.Column="1" Background="cyan" />
<Rectangle Grid.Column="2" Name="SpacerSegment"
HorizontalAlignment="Stretch" Fill="red" Height="40"
Width="{Binding Duration}">
</Rectangle>
<GridSplitter Grid.Column="3" Background="cyan" />
<Panel Grid.Column="4" Name="SpacerRight"/>
</Grid>
Это работает так, как будто я могу визуально изменить размер сегмента:
Тем не менее, я изо всех сил пытаюсь вернуть изменения размера в модель представления, которую вы также можете видеть в красной области, не меняя размер. Я не смог найти способ получить изменения ширины элементов управления SpacerLeft
или SpacerSegment
.
Вместо этого я попытался удалить выделенные свойства Width
и вместо этого привязать ColumnDefinitions
сетки. Я добавил это свойство в свою модель представления:
public ColumnDefinitions ColumnDefinitions
{
get => ColumnDefinitions.Parse($"{From},3,{Duration},3,*");
set
{
From = value[0].ActualWidth;
Duration = value[2].ActualWidth;
}
}
и изменил представление XAML на это:
<Grid ColumnDefinitions="{Binding ColumnDefinitions}" HorizontalAlignment="Stretch">
<Panel Grid.Column="0" Name="SpacerLeft" />
<GridSplitter Grid.Column="1" Background="cyan" />
<Rectangle Grid.Column="2" Name="SpacerSegment"
HorizontalAlignment="Stretch" Fill="red" Height="40">
</Rectangle>
<GridSplitter Grid.Column="3" Background="cyan" />
<Panel Grid.Column="4" Name="SpacerRight"/>
</Grid>
Но это не скомпилируется по причине, которая, к сожалению, не имеет для меня особого смысла:
InvalidCastException: Unable to cast object of type 'Avalonia.Data.Binding' to type 'Avalonia.Controls.ColumnDefinition'. System.InvalidCastException: Unable to cast object of type 'Avalonia.Data.Binding' to type 'Avalonia.Controls.ColumnDefinition'.
at Avalonia.Collections.AvaloniaList`1.System.Collections.IList.Add(Object value) in /_/src/Avalonia.Base/Collections/AvaloniaList.cs:line 520
at Builder_1ee6d795025442edb279bcc7110e88eb_avares://AvaloniaOutseekClient/Views/MomentsSourceView.axaml.XamlClosure_2.Build(IServiceProvider )
at Avalonia.Markup.Xaml.XamlIl.Runtime.XamlIlRuntimeHelpers.<>c__DisplayClass0_0.<DeferredTransformationFactoryV1>b__0(IServiceProvider sp) in /_/src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs:line 28
at Avalonia.Markup.Xaml.Templates.TemplateContent.Load(Object templateContent) in /_/src/Markup/Avalonia.Markup.Xaml/Templates/TemplateContent.cs:line 17
at Avalonia.Markup.Xaml.Templates.DataTemplate.Build(Object data, IControl existing) in /_/src/Markup/Avalonia.Markup.Xaml/Templates/DataTemplate.cs:line 33
at Avalonia.Controls.Presenters.ContentPresenter.CreateChild() in /_/src/Avalonia.Controls/Presenters/ContentPresenter.cs:line 356
...