Avalonia学习

官网

1、图片

  • 图片显示

Source设置为固定的图片全路径时,可以直接设置;

但是用Binding绑定图片时,需要是Bitmap类型,即 Avalonia.Media.Imaging.Bitmap(Stream stream); 

<Image Grid.Column="0" Grid.Row="2" Width="11" Source="/Assets/icon/fav.png"  HorizontalAlignment="Center" VerticalAlignment="Center"></Image>

<Image Cursor="Hand" Name="Signature" Tapped="Tapped_Detail" Source="{Binding MailDetailModel.SignImage, Converter={StaticResource ImgConverter}}"></Image>
  • 图片单击

1、使用Tapped=“Tapped_Detail”  Tapped_Detail定义在页面后端的cs代码中

2、使用Image.GestureRecognizers,其中没有TapGestureRecognizer【不可用】

3、使用<Button>包裹,命令可写在viewmodel中

注意设置Button的属性

<Button  Command="{Binding ShowDecryptCert}" BorderThickness="0" Background="White">
              <Image Source="{Binding MailDetailModel.ResolveResult, Converter={StaticResource MailResolveResultDecryptConverter}}"></Image>
            </Button>

2、文本TextBlock 

  • 文本截断与显示不全用ToolTip
 <TextBlock  Text="{Binding Subject}"  Width="180" TextTrimming="CharacterEllipsis" TextWrapping="NoWrap" ToolTip.Tip="{Binding Subject}"></TextBlock>

参考:WPF 文字换行TextWrapping 显示不全用省略号TextTrimming 显示不全弹提示内容ToolTip

注意宽度的设置:

如果控件位于grid中,则设置列宽,如下:

<Grid VerticalAlignment="Center" Background="Transparent">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                            <ColumnDefinition Width="180"></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                        </Grid.ColumnDefinitions>

    <TextBlock x:Name="content" Margin="10" Text="{Binding FolderName}" FontSize="14" Grid.Column="1" TextTrimming="CharacterEllipsis" TextWrapping="NoWrap" ToolTip.Tip="{Binding FolderName}"/>

ToolTip.Placement="Right"  右下角

Left:左下角

AnchorAndGravity:底部中间

想置于上方,必须同时设置这两个:ToolTip.Placement="Top" ToolTip.VerticalOffset="-5"  【因为原点在左上角,往下为正】

  • 文本绑定多个值,单击事件获取

通过ToolTip去传递另一个对象(不需要其显示,通过ShowDelay 来控制其不显示【鼠标放在上面的显示需要等待的毫秒数】)

<TextBlock Cursor="Hand" Name="Receiver" Tapped="ShowSenderInfo" Classes="B" Foreground="{StaticResource GrayBrush3}"  Text="{Binding NickName}" ToolTip.Tip="{Binding Address}"  ToolTip.ShowDelay="3000"></TextBlock>

后台获取ToolTip绑定的对象

public async void ShowSenderInfo(object Sender, Avalonia.Interactivity.RoutedEventArgs e)
        {
            try
            {
                var sender = Sender as TextBlock;
                if (sender == null)
                    return;
                string mailaddress = ToolTip.GetTip(sender).ToString(); //联系人的邮箱地址
            }
            catch (Exception)
            {
            }
        }

3、ListBox

右键事件

PointerPressed 事件,xml中 PointerPressed="ListBox_MouseTap"

 private void ListBox_MouseTap(object sender, Avalonia.Input.PointerPressedEventArgs e)
        {
            try
            {
                if (e.MouseButton == Avalonia.Input.MouseButton.Right)
                {
                    MyListBox control = null;
                    if (sender is MyListBox)
                        control = sender as MyListBox;
                    if (control != null && control.SelectedItem != null)
                    {
                        MailListModel model = control.SelectedItem as MailListModel;
                        if (model != null)
                        {
                            model.IsRightSelected = true;
                            vm.SelectedItem = model;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.AddErrorLog(ex);
            }
        }
View Code

参考:.NET 跨平台框架Avalonia UI: 填坑指北(一):熟悉UI操作

4、更新UI

后台线程 想执行UI操作,必须用以下方式

await Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() =>
{
MailCache.Instance.ShowMailFolders(mailFolderInfos);
});

5、WebView

1、同一个页面没法用两个

 2、给webview设置值后,执行后续逻辑 用Task.Delay().ContinueWith() 以防止webview的卡顿与延迟。

//防止切换卡顿
await Task.Delay(100).ContinueWith(async t =>
{
....
});

6、Window窗体 

不显示 顶部:SystemDecorations="BorderOnly"

7、样式Style

  • 样式引用

<!--Classes="MenuList"的ListBox的样式-->
<Style Selector="ListBox.MenuList">
</Style>

<ListBox x:Name="lvMenu" Classes="MenuList" Items="{Binding MenuNames}" ></ListBox>

  • 字体

避免中文乱码:<Setter Property="FontFamily" Value="苹方-简,Microsoft YaHei,宋体-简"></Setter>

下划线正常显示:<Setter Property="FontFamily" Value="Microsoft YaHei"></Setter>

8、Grid

<RowDefinition Height="Auto"></RowDefinition>与<RowDefinition Height="*"></RowDefinition> 的区别

前者的高度会根据其元素的高度而定,当窗体最大化后也不会变;

后者的高度在窗体最大化时会改变。

学习

论坛:https://gitter.im/AvaloniaUI/Avalonia

jason成都

常见问题

1、在Linux环境下,打开文件对话框报错:String reference not set to an instance of a String. (Parameter 's')

具体报错信息:String reference not set to an instance of a String. (Parameter 's')

at System.Text.Encoding.GetBytes(String s)
at Avalonia.X11.X11Window.SetTitle(String title)
at Avalonia.Controls.Window.<>c.<.cctor>b__25_0(Window s, AvaloniaPropertyChangedEventArgs e)
at System.Reactive.Subjects.Subject`1.OnNext(T value) in /_/Rx.NET/Source/src/System.Reactive/Subjects/Subject.cs:line 148
at Avalonia.AvaloniaObject.RaisePropertyChanged[T](AvaloniaPropertyChangedEventArgs`1 change)
at Avalonia.AvaloniaObject.Avalonia.PropertyStore.IValueSink.ValueChanged[T](AvaloniaPropertyChangedEventArgs`1 change)
at Avalonia.ValueStore.SetValue[T](StyledPropertyBase`1 property, T value, BindingPriority priority)
at Avalonia.Controls.Window.set_Title(String value)
at Avalonia.Dialogs.ManagedFileDialogExtensions.ManagedSystemDialogImpl`1.Show(SystemDialog d, Window parent, ManagedFileDialogOptions options)
at Avalonia.Dialogs.ManagedFileDialogExtensions.ManagedSystemDialogImpl`1.ShowFileDialogAsync(FileDialog dialog, Window parent)
at Avalonia.Controls.SaveFileDialog.ShowAsync(Window parent)

at mesignpctest.Helper.FileDialogHelper.OpenSaveFileDialog(Window win, String fileName) in F:WoTProjectMeSignClientMeSignmesignpctestHelperFileDialogHelper.cs:line 180
at mesignpctest.Helper.AttachmentFileHelper.SaveFile(Window win, AttachmentListModel model, Boolean fromAttachList)
in F:WoTProjectMeSignClientMeSignmesignpctestHelperAttachmentFileHelper.cs:line 154

注意 ,红色部分

找到代码,

//弹出文件目录选择框
var fileDialog = new SaveFileDialog();
fileDialog.InitialFileName = fileName;
//获取选中的路径地址
var path = await fileDialog.ShowAsync(win);
return path;

可以发现 对话框没有设置Title,改为如下 即可

 var fileDialog = new SaveFileDialog() { Title = AppResource.另存为 };

2、Main throw a exception:System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')

at System.Collections.Generic.List`1.get_Item(Int32 index)

   at System.Collections.ObjectModel.Collection`1.System.Collections.IList.get_Item(Int32 index)

   at Avalonia.Controls.Utils.IEnumerableUtils.ElementAt(IEnumerable items, Int32 index)

   at Avalonia.Controls.Presenters.ItemVirtualizerSimple.RecycleContainers()

   at Avalonia.Controls.Presenters.ItemVirtualizerSimple.RecycleContainersOnRemove()

   at Avalonia.Controls.Presenters.ItemVirtualizerSimple.ItemsChanged(IEnumerable items, NotifyCollectionChangedEventArgs e)

   at Avalonia.Controls.Presenters.ItemsPresenter.ItemsChanged(NotifyCollectionChangedEventArgs e)

   at Avalonia.Controls.Presenters.ItemsPresenterBase.set_Items(IEnumerable value)

   at Avalonia.Controls.Presenters.ItemsPresenterBase.<>c.<.cctor>b__7_2(ItemsPresenterBase o, IEnumerable v)

   at Avalonia.DirectProperty`2.InvokeSetter(IAvaloniaObject instance, BindingValue`1 value)

   at Avalonia.AvaloniaObject.SetDirectValueUnchecked[T](DirectPropertyBase`1 property, BindingValue`1 value)

   at Avalonia.AvaloniaObject.DirectBindingSubscription`1.OnNext(BindingValue`1 value)

   at Avalonia.Reactive.SingleSubscriberObservableBase`1.PublishNext(T value)

   at Avalonia.Reactive.TypedBindingAdapter`1.OnNext(BindingValue`1 value)

   at Avalonia.Reactive.SingleSubscriberObservableBase`1.PublishNext(T value)

   at Avalonia.Reactive.BindingValueAdapter`1.OnNext(T value)

   at Avalonia.Reactive.SingleSubscriberObservableBase`1.PublishNext(T value)

   at Avalonia.Data.TemplateBinding.PublishValue()

   at Avalonia.AvaloniaObject.RaisePropertyChanged[T](AvaloniaPropertyChangedEventArgs`1 change)

   at Avalonia.AvaloniaObject.RaisePropertyChanged[T](AvaloniaProperty`1 property, Optional`1 oldValue, BindingValue`1 newValue, BindingPriority priority)

   at Avalonia.AvaloniaObject.SetAndRaise[T](AvaloniaProperty`1 property, T& field, T value)

   at Avalonia.Controls.ItemsControl.set_Items(IEnumerable value)

   at Avalonia.Controls.ItemsControl.<>c.<.cctor>b__8_4(ItemsControl o, IEnumerable v)

   at Avalonia.DirectProperty`2.InvokeSetter(IAvaloniaObject instance, BindingValue`1 value)

   at Avalonia.AvaloniaObject.SetDirectValueUnchecked[T](DirectPropertyBase`1 property, BindingValue`1 value)

   at Avalonia.AvaloniaObject.DirectBindingSubscription`1.<>c__DisplayClass7_0.<OnNext>b__0()

   at Avalonia.Threading.JobRunner.RunJobs(Nullable`1 priority)

   at Avalonia.Win32.Win32Platform.WndProc(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam)

   at Avalonia.Win32.Interop.UnmanagedMethods.DispatchMessage(MSG& lpmsg)

   at Avalonia.Win32.Win32Platform.RunLoop(CancellationToken cancellationToken)

   at Avalonia.Threading.Dispatcher.MainLoop(CancellationToken cancellationToken)

   at Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime.Start(String[] args)

   at Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime[T](T builder, String[] args, ShutdownMode shutdownMode)

   at mesign.pc.Program.Main(String[] args) in F:WoTProjectMeSignClientMeSignmesign.pcProgram.cs:line 22

场景:一直快速切换文件夹时 出现闪退

解决方法:查看Avalonia.Controls.Presenters.ItemVirtualizerSimple 源代码,,

RecycleContainersOnRemove() 中RecycleContainers()

联想到 切换文件夹时的代码,每次切换时 对MailItems做了一次清空,然后给MailItems赋值。。

改为:切换文件夹时不清空列表,直接对它进行赋值。 文件夹没有邮件时才清空列表。

原文地址:https://www.cnblogs.com/peterYong/p/13671460.html