AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题

问题[maui](coding)

Martin Hope
rochitsen
Asked: 2025-04-30 13:52:06 +0800 CST

使用 CommandParameter 设置属性时,不会保留类属性值

  • 6

CommandParameter我在 .net maui 9 中有一个下面的小例子,其中我通过在视图中单击按钮时设置的值来设置视图模型中的属性。

然后将此属性用作视图的属性BindingContext。因此,单击按钮时应显示的文本为。PlaceHolderTextEntryEntrySet PropertyOneText from Property

查看以下代码:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiBindingExample.MainPage"
             xmlns:local="clr-namespace:MauiBindingExample.ViewModels">

    <ScrollView>
        <VerticalStackLayout 
            Padding="30,0"
            Spacing="25">
            <Image
                Source="dotnet_bot.png"
                HeightRequest="185"
                Aspect="AspectFit"
                SemanticProperties.Description="dot net bot in a hovercraft number nine" />
            <Button
                BindingContext="{local:ExampleViewModel}"
                x:DataType="local:ExampleViewModel"
                Text="Set PropertyOne" 
                Command="{Binding SetPropertyOneCommand}"
                CommandParameter="Text from Property"/>
            <Entry
                BindingContext="{local:ExampleViewModel}"
                x:DataType="local:ExampleViewModel"
                PlaceholderColor="AliceBlue"
                Placeholder="{Binding EntryPlaceholderText}"/>
        </VerticalStackLayout>
    </ScrollView>
</ContentPage>

视图模型的代码如下:

using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;

namespace MauiBindingExample.ViewModels
{
    public class ExampleViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private string entryPlaceholderText;

        public string EntryPlaceholderText
        {
            get => entryPlaceholderText;
            set
            {
                entryPlaceholderText = value;
                OnPropertyChanged();
            }
        }
        
        public ICommand SetPropertyOneCommand { get; set; }

        public ExampleViewModel()
        {
            SetPropertyOneCommand = new Command<string>(
                (string arg) =>
                {
                    EntryPlaceholderText = arg;
                });
        }
        public void OnPropertyChanged([CallerMemberName] string propertyName="")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

当我设置调试器时,我可以确认单击按钮时属性EntryPlaceholderText设置正确Set PropertyOne,但是在命令执行完成后,属性EntryPlaceholderText被重置,因此没有Entry显示占位符文本。

可能存在什么问题?

非常感谢您的帮助。

maui
  • 1 个回答
  • 42 Views
Martin Hope
Prescott Chartier
Asked: 2025-03-07 03:36:58 +0800 CST

Maui App 连接到 Visual Studio 时以调试模式运行,但独立运行时崩溃

  • 5

我已将问题缩小到Flyout菜单 xaml 代码中的某个部分,但无法查明原因。我的 xaml:

        <VerticalStackLayout
            x:Name="Flyout"
            WidthRequest="260"
            HorizontalOptions="Start"
            Spacing="2"
            Grid.Row="1"
            BackgroundColor="Gold"
            TranslationX="-250">
            <HorizontalStackLayout HorizontalOptions="Start" HeightRequest="50" >
                <Image Source="addEmployee.jpg" Style="{StaticResource IconLabelStyle}" />
                <Label x:Name="AddEmployee" Text="Add Employee" Style="{StaticResource LabelStyle}" />
                <HorizontalStackLayout.GestureRecognizers>
                    <TapGestureRecognizer Tapped="OnMenuItemTap" CommandParameter="Add Another Participant"/>
                </HorizontalStackLayout.GestureRecognizers>
            </HorizontalStackLayout>
            <HorizontalStackLayout HorizontalOptions="Start" HeightRequest="50">
                <Image Source="assign.jpg" Style="{StaticResource IconLabelStyle}" />
                <Label x:Name="Assign" Text="Assign Employee To Section" Style="{StaticResource LabelStyle}" />
                <HorizontalStackLayout.GestureRecognizers>
                    <TapGestureRecognizer Tapped="OnMenuItemTap" CommandParameter="Re-Register"/>
                </HorizontalStackLayout.GestureRecognizers>
            </HorizontalStackLayout>
            <HorizontalStackLayout HorizontalOptions="Start" HeightRequest="50">
                <Image Source="text.jpg" Style="{StaticResource IconLabelStyle}" />
                <Label x:Name="sendtext" Text="Send Text" Style="{StaticResource LabelStyle}" />
                <HorizontalStackLayout.GestureRecognizers>
                    <TapGestureRecognizer Tapped="OnMenuItemTap" CommandParameter="ChatRoom"/>
                </HorizontalStackLayout.GestureRecognizers>
            </HorizontalStackLayout>
            <HorizontalStackLayout HorizontalOptions="Start" HeightRequest="50">
                <Image Source="myaccount.jpg" Style="{StaticResource IconLabelStyle}" />
                <Label x:Name="MyAccount" Text="My Account" Style="{StaticResource LabelStyle}" />
                <HorizontalStackLayout.GestureRecognizers>
                    <TapGestureRecognizer Tapped="OnMenuItemTap" CommandParameter="My Account"/>
                </HorizontalStackLayout.GestureRecognizers>
            </HorizontalStackLayout>
            <HorizontalStackLayout HorizontalOptions="Start" HeightRequest="50">
                <Image Source="myaccount.jpg" Style="{StaticResource IconLabelStyle}" />
                <Label x:Name="LogOut" Text="Log Off" Style="{StaticResource LabelStyle}" />
                <HorizontalStackLayout.GestureRecognizers>
                    <TapGestureRecognizer Tapped="OnMenuItemTap" CommandParameter="Log Off"/>
                </HorizontalStackLayout.GestureRecognizers>
            </HorizontalStackLayout>
        </VerticalStackLayout>

当我注释掉Flyout代码时,应用程序将在调试器之外运行。我转储了测试设备崩溃日志,在其中发现了以下内容:

03-05 20:52:00.570 10573  4825  4825 I MonoDroid: UNHANDLED EXCEPTION:
03-05 20:52:00.575 10573  4825  4825 I MonoDroid: Android.Runtime.JavaProxyThrowable: Exception of type 'Android.Runtime.JavaProxyThrowable' was thrown.
03-05 20:52:00.575 10573  4825  4825 I MonoDroid: 
03-05 20:52:00.575 10573  4825  4825 I MonoDroid:   --- End of managed Android.Runtime.JavaProxyThrowable stack trace ---
03-05 20:52:00.575 10573  4825  4825 I MonoDroid: android.runtime.JavaProxyThrowable: [System.InvalidCastException]: Specified cast is not valid.
03-05 20:52:00.575 10573  4825  4825 I MonoDroid:   at Microsoft.Maui.Controls.Xaml.ApplyPropertiesVisitor.SetPropertyValue + 0xb9(Unknown Source)
03-05 20:52:00.575 10573  4825  4825 I MonoDroid:   at Microsoft.Maui.Controls.Xaml.ApplyPropertiesVisitor.Visit + 0xf6(Unknown Source)
03-05 20:52:00.575 10573  4825  4825 I MonoDroid:   at Microsoft.Maui.Controls.Xaml.ElementNode.Accept + 0x90(Unknown Source)
03-05 20:52:00.575 10573  4825  4825 I MonoDroid:   at Microsoft.Maui.Controls.Xaml.ElementNode.Accept + 0x3e(Unknown Source)
03-05 20:52:00.575 10573  4825  4825 I MonoDroid:   at Microsoft.Maui.Controls.Xaml.ElementNode.Accept + 0x67(Unknown Source)
03-05 20:52:00.575 10573  4825  4825 I MonoDroid:   at Microsoft.Maui.Controls.Xaml.ElementNode.Accept + 0x67(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at Microsoft.Maui.Controls.Xaml.ElementNode.Accept + 0x67(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at Microsoft.Maui.Controls.Xaml.ElementNode.Accept + 0x67(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at Microsoft.Maui.Controls.Xaml.RootNode.Accept + 0x81(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at Microsoft.Maui.Controls.Xaml.XamlLoader.Visit + 0x97(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at Microsoft.Maui.Controls.Xaml.XamlLoader.Load + 0x9d(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at Microsoft.Maui.Controls.Xaml.XamlLoader.Load + 0x0(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at Microsoft.Maui.Controls.Xaml.XamlLoader.Load + 0x29(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at Microsoft.Maui.Controls.Xaml.Extensions.LoadFromXaml + 0x0(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at MyApp.RegUser.InitializeComponent + 0x1(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at MyApp.RegUser..ctor + 0xa0(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at MyApp.Logon+<SignOn>d__6.MoveNext + 0x7b6(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw + 0x11(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess + 0x37(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification + 0x2d(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd + 0x8(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at System.Runtime.CompilerServices.TaskAwaiter.GetResult + 0x0(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at MyApp.Logon+<<OnCounterClicked>b__5_0>d.MoveNext + 0x73(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw + 0x11(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess + 0x37(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification + 0x2d(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd + 0x8(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at System.Runtime.CompilerServices.TaskAwaiter.GetResult + 0x0(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at MyApp.Logon+<OnCounterClicked>d__5.MoveNext + 0xf4(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw + 0x11(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at System.Threading.Tasks.Task+<>c.<ThrowAsync>b__128_0 + 0x0(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 + 0x0(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at Java.Lang.Thread+RunnableImplementor.Run + 0x8(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at Java.Lang.IRunnableInvoker.n_Run + 0x0(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V + 0x5(Unknown Source)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at mono.java.lang.RunnableImplementor.n_run(Native Method)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:29)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at android.os.Handler.handleCallback(Handler.java:958)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at android.os.Handler.dispatchMessage(Handler.java:99)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at android.os.Looper.loopOnce(Looper.java:230)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at android.os.Looper.loop(Looper.java:319)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at android.app.ActivityThread.main(ActivityThread.java:9063)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at java.lang.reflect.Method.invoke(Native Method)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:588)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
03-05 20:52:00.576 10573  4825  4825 I MonoDroid: 
03-05 20:52:00.576 10573  4825  4825 I MonoDroid:   --- End of managed Android.Runtime.JavaProxyThrowable stack trace ---

此行出现错误Specified cast is not valid. at Microsoft.Maui.Controls.Xaml.ApplyPropertiesVisitor.SetPropertyValue + 0xb9(Unknown Source)

我没有在其中看到任何可以确定演员异常的信息。也许另一双眼睛可以找到。

maui
  • 1 个回答
  • 28 Views
Martin Hope
Kraken
Asked: 2025-03-03 02:58:42 +0800 CST

Maui - 打字时网格列的大小会发生变化

  • 5

我的目标是窗口平台。

我已经创建了一个带有网格的内容视图,如下所示:

    <Grid RowDefinitions="auto,auto,auto,auto,auto,auto,auto" ColumnDefinitions="*,*,*"
      BackgroundColor="Yellow"
      ColumnSpacing="3" RowSpacing="3">
    <Entry Placeholder="Strada"
           Grid.ColumnSpan="2"
            ToolTipProperties.Text="Strada"
            Text="{Binding Indirizzo.Strada}" />
    <Entry ToolTipProperties.Text="Civico"
            Grid.Column="2"
            Text="{Binding Indirizzo.Civico}" />
    <Entry Placeholder="Cap"
            Grid.Row="1"
            ToolTipProperties.Text="Cap"
            Text="{Binding Indirizzo.Cap}" />
    <Entry ToolTipProperties.Text="Località"
            Grid.Row="1"
            Grid.Column="1"
            Grid.ColumnSpan="2"
            Placeholder="Località"
            Text="{Binding Indirizzo.Localita}" />
    <Entry Placeholder="Provincia"
            Grid.Row="2"
            Grid.ColumnSpan="3"
            ToolTipProperties.Text="Provincia"
            Text="{Binding Indirizzo.Provincia}" />

    <Entry Placeholder="Nazione"
            Grid.Row="3"
           Grid.ColumnSpan="3"
            Text="{Binding Indirizzo.Nazione}"
            ToolTipProperties.Text="Nazione di provenienza" />
    <Switch IsToggled="{Binding Indirizzo.Attivo}"
            Grid.Row="4"
            ToolTipProperties.Text="Attivare o disattivare l'indirizzo" />
    <Button Text="Save"
            Grid.Row="5"
            Grid.Column="0" Grid.ColumnSpan="1"
            BackgroundColor="DodgerBlue"
            MinimumHeightRequest="15" 
            Command="{Binding SaveCommand}"
            CornerRadius="0"
            Padding="20,5"/>
    <Button Text="Reset"
            Grid.Row="5"
            Grid.Column="1"
            BackgroundColor="Red"
            MinimumHeightRequest="15"
            CornerRadius="0"
            Padding="20,5" 
            Command="{Binding ResetCommand}"/>

此 contentview 在另一个 contentview 中用作:

        <views:IndirizzoImpiegatoTemplate Grid.Row="4"
                                      MaximumWidthRequest="600"
                                      BindingContext="{Binding Impiegato.Residenza}"
                                      HorizontalOptions="Start"
                                      Grid.Column="1"/>

一开始,网格并没有使用所有可用空间。我向你展示发生了什么:

动态图

并且保存按钮的文字颜色是黑色,而不是像重置按钮那样是白色。

        <Button Text="Save"
            Grid.Row="5"
            Grid.Column="0" Grid.ColumnSpan="1"
            BackgroundColor="DodgerBlue"
            MinimumHeightRequest="15" 
            Command="{Binding SaveCommand}"
            CornerRadius="0"
            Padding="20,5"/>
    <Button Text="Reset"
            Grid.Row="5"
            Grid.Column="1"
            BackgroundColor="Red"
            MinimumHeightRequest="15"
            CornerRadius="0"
            Padding="20,5" 
            Command="{Binding ResetCommand}"/>

如果我删除命令,它可以正常工作。

更新

    public partial class IndirizzoImpiegatoViewModel:ObservableObject
{
    IndirizzoImpiegatoModelView? _old;
    IDialogService _dialog;
    public IndirizzoImpiegatoViewModel(ICollection<IndirizzoImpiegatoModel>? indi=null)
    {
        _dialog =IPlatformApplication.Current!.Services.GetRequiredService<IDialogService>();
        if (indi is not null)
            Indirizzi = new(indi!.Select(c => new IndirizzoImpiegatoModelView(c)));
        //else Indirizzi = new();

        Indirizzo = new();

        Indirizzo.PropertyChanged += (s, e) =>
        {
            SaveCommand.NotifyCanExecuteChanged();
        };
    }

    [ObservableProperty] IndirizzoImpiegatoModelView? _indirizzo;
    [ObservableProperty]
    ObservableCollection<IndirizzoImpiegatoModelView>? _indirizzi;
    [ObservableProperty] IndirizzoImpiegatoModelView? _indirizzoSelezionato;

    [RelayCommand(CanExecute =nameof(CanSave))]
    void Save()
    {
        if(Indirizzi is null)Indirizzi=new();
        if(_old is null)
            Indirizzi!.Add(Indirizzo!);
        else
        {
            IndirizzoImpiegatoModelView? indiToEdit=Indirizzi.Where(c=>c.Id==_old.Id).FirstOrDefault();
            indiToEdit = Indirizzo;
        }
        Indirizzo=new();
    }
    bool CanSave()
    {
        
        if(Indirizzo!.HasErrors)return false;

        if (_old is not null && _old.IsEqualJson(Indirizzo)) return true;
        if (!Indirizzo!.IsEqualJson(_old!)) return true;
        else return false;
    }

    [RelayCommand]
    async Task DeleteItem(IndirizzoImpiegatoModelView item)
    {
        var result=await _dialog.DisplayAlertYesNoAsync("Elimina item", "Desideri eliminare l'item selezionato?", "Si", "No");
        if(result)
            Indirizzi?.Remove(item);
    }

    [RelayCommand]
    void EditItem(IndirizzoImpiegatoModelView item)
    {
        Indirizzo=item;
        
    }

    [RelayCommand]
    void Reset()
    {
        Indirizzo = new();
    }

}

这是父模板。它是一个内容视图:

    <?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiApp1.Views.EmploeeTemplate"
             xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
             xmlns:mod="clr-namespace:MauiApp1.ViewModel"
             xmlns:views="clr-namespace:MauiApp1.Views"
             x:DataType="mod:ImpiegatoViewModel">
    <ContentView.Resources>
        <Style TargetType="Entry">
            <Setter Property="TextTransform"
                    Value="Uppercase" />
            <Setter Property="ClearButtonVisibility"
                    Value="WhileEditing" />
        </Style>
    </ContentView.Resources>
    <Grid RowDefinitions="auto,auto,auto,auto,auto,auto,auto,auto,auto,auto,auto,auto,auto,auto"
          ColumnDefinitions="auto,auto" ColumnSpacing="5" RowSpacing="5" Margin="20">
        <Label Text="Immagine"
               FontAttributes="Bold"
               HorizontalTextAlignment="End" />
        <Border Stroke="Gray"
                StrokeThickness="1"
                Grid.Column="1"
                HorizontalOptions="Start"
                Padding="3">
            <Image MinimumWidthRequest="150"
                   MaximumWidthRequest="200"
                   HorizontalOptions="Start"
                   MinimumHeightRequest="150"
                   MaximumHeightRequest="200"
                   BackgroundColor="LightGray"
                   Aspect="AspectFit"
                   Source="{Binding Impiegato.Immagine.FullPath,Mode=TwoWay}">
                <Image.GestureRecognizers>
                    <TapGestureRecognizer Command="{Binding SelectImageCommand}" />
                </Image.GestureRecognizers>
            </Image>
        </Border>
        <Label FontAttributes="Bold"
               HorizontalOptions="End"
               VerticalOptions="Center"
               Text="Cognome e nome"
               Grid.Row="1" />
        <HorizontalStackLayout Spacing="5" Grid.Column="1" Grid.Row="1">
            <Entry Placeholder="Cognome"
                   MinimumWidthRequest="200"
                   Text="{Binding Impiegato.Cognome}"/>
            <Entry Placeholder="Nome"
                   MinimumWidthRequest="200"
                   Text="{Binding Impiegato.Nome}"/>
        </HorizontalStackLayout>
        <Label FontAttributes="Bold"
               Text="Luogo nascita"
               HorizontalOptions="End"
               VerticalOptions="Center"
               Grid.Row="2" />
        <HorizontalStackLayout Spacing="5"
                               Grid.Column="1"
                               Grid.Row="2">
            <Entry Placeholder="Località nascita"
                   MinimumWidthRequest="150"
                   Text="{Binding Impiegato.LuogoNascita}" />
            <Entry Placeholder="Provincia nascita"
                   MinimumWidthRequest="150"
                   Text="{Binding Impiegato.ProvinciaNascita}" />
            <Entry Placeholder="Nazionalità"
                   MinimumWidthRequest="150"
                   Text="{Binding Impiegato.Nazionalita}" />
        </HorizontalStackLayout>
        <Label FontAttributes="Bold"
               Text="Data nascita"
               HorizontalOptions="End"
               VerticalOptions="Center"
               BackgroundColor="Yellow"
               Grid.Row="3" />
        <DatePicker Grid.Row="3" BackgroundColor="Yellow"
                    Grid.Column="1"
                    MinimumHeightRequest="12"
                    VerticalOptions="Center"
                    Date="{Binding Impiegato.DataNascita}" />
        <Label FontAttributes="Bold"
               Text="Residenza"
               HorizontalOptions="End"
               VerticalOptions="Start"
               BackgroundColor="Yellow"
               Grid.Row="4" />
        <views:IndirizzoImpiegatoTemplate Grid.Row="4"
                                          MaximumWidthRequest="600"
                                          BindingContext="{Binding Impiegato.Residenza}"
                                          HorizontalOptions="Start"
                                          Grid.Column="1"/>

    </Grid>
</ContentView>

Tihi 是 IndirizzoImpiegato 模板。这是一个内容视图:

<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:mod="clr-namespace:MauiApp1.ViewModel"
             xmlns:mv="clr-namespace:MauiApp1.ModelView"
             x:DataType="mod:IndirizzoImpiegatoViewModel"
             x:Class="MauiApp1.Views.IndirizzoImpiegatoTemplate">
    <ContentView.Resources>
        <!--<DataTemplate x:Key="ItemTemplate" x:DataType="mv:IndirizzoImpiegatoModelView">
            <HorizontalStackLayout Padding="5">
                <Label>
                    <Label.Text>
                        <MultiBinding StringFormat="{}{0}, {1}&#x0a;{2} {3}&#x0a;{4}">
                            <Binding Path="{Binding Strada}"/>
                            <Binding Path="{Binding Civico}" />
                            <Binding Path="{Binding Cap}" />
                            <Binding Path="{Binding Localita}" />
                            <Binding Path="{Binding Provincia}" />
                        </MultiBinding>
                    </Label.Text>
                </Label>
                <ImageButton Source="edit.svg"
                             x:DataType="mod:IndirizzoImpiegatoViewModel"
                             Command="{Binding EditItemCommand}"
                             CommandParameter="{Binding}" />
                <ImageButton Source="delete.svg"
                             x:DataType="mod:IndirizzoImpiegatoViewModel" 
                             Command="{Binding DeleteItemCommand}"
                             CommandParameter="{Binding}"/>
            </HorizontalStackLayout>
        </DataTemplate>-->
    </ContentView.Resources>
    <Grid RowDefinitions="auto,auto,auto,auto,auto,auto,auto" ColumnDefinitions="*,*,*"
          BackgroundColor="Yellow"
          ColumnSpacing="3" RowSpacing="3">
        <Entry Placeholder="Strada"
               Grid.ColumnSpan="2"
                ToolTipProperties.Text="Strada"
                Text="{Binding Indirizzo.Strada}" />
        <Entry ToolTipProperties.Text="Civico"
                Grid.Column="2"
                Text="{Binding Indirizzo.Civico}" />
        <Entry Placeholder="Cap"
                Grid.Row="1"
                ToolTipProperties.Text="Cap"
                Text="{Binding Indirizzo.Cap}" />
        <Entry ToolTipProperties.Text="Località"
                Grid.Row="1"
                Grid.Column="1"
                Grid.ColumnSpan="2"
                Placeholder="Località"
                Text="{Binding Indirizzo.Localita}" />
        <Entry Placeholder="Provincia"
                Grid.Row="2"
                Grid.ColumnSpan="3"
                ToolTipProperties.Text="Provincia"
                Text="{Binding Indirizzo.Provincia}" />

        <Entry Placeholder="Nazione"
                Grid.Row="3"
               Grid.ColumnSpan="3"
                Text="{Binding Indirizzo.Nazione}"
                ToolTipProperties.Text="Nazione di provenienza" />
        <Switch IsToggled="{Binding Indirizzo.Attivo}"
                OnColor="DodgerBlue"
                Grid.Row="4"
                ToolTipProperties.Text="Attivare o disattivare l'indirizzo" />
        <Button Text="Save"
                Grid.Row="5"
                Grid.Column="0" Grid.ColumnSpan="1"
                BackgroundColor="DodgerBlue"
                MinimumHeightRequest="15" 
                CornerRadius="0"
                Command="{Binding SaveCommand}"
                Padding="20,5"/>
        <Button Text="Reset"
                Grid.Row="5"
                Grid.Column="1"
                BackgroundColor="Red"
                MinimumHeightRequest="15"
                CornerRadius="0"
                Padding="20,5" 
                Command="{Binding ResetCommand}"/>
        <FlexLayout BindableLayout.ItemsSource="{Binding Indirizzi}"
                    Grid.Row="6"
                    Grid.ColumnSpan="3"
                    Direction="Row"
                    Wrap="Wrap"
                    JustifyContent="Start">
            <BindableLayout.ItemTemplate>
                <DataTemplate x:DataType="mv:IndirizzoImpiegatoModelView">
                  <Border Margin="0,0,3,3"
                          StrokeThickness="4"
                        BackgroundColor="BlanchedAlmond"
                        Stroke="Black">
                        <Border.Triggers>
                            <DataTrigger TargetType="Border"
                                         Binding="{Binding Attivo}"
                                         Value="true">
                                <Setter Property="BackgroundColor"
                                        Value="Bisque" />
                                <Setter Property="ToolTipProperties.Text"
                                        Value="Indirizzo attivo" />
                                <Setter Property="Stroke"
                                        Value="Red" />
                            </DataTrigger>
                        </Border.Triggers>
                    <Grid RowDefinitions="auto,auto,auto"
                          ColumnDefinitions="auto,auto,auto"
                          ColumnSpacing="10"
                          Padding="5">
                        <HorizontalStackLayout Spacing="5">
                            <Label Text="{Binding Strada}"
                                   FontAttributes="Bold"
                                   VerticalOptions="Center"
                                   MinimumHeightRequest="12" />
                            <Label Text="{Binding Civico}"
                                   VerticalOptions="Center"
                                   FontAttributes="Bold"
                                   MinimumHeightRequest="12"/>

                        </HorizontalStackLayout>
                        <HorizontalStackLayout Grid.Row="1"
                                               Spacing="5">
                            <Label Text="{Binding Cap}"/>
                            <Label Text="{Binding Localita}"/>
                            <Label Text="{Binding Provincia}"/>

                        </HorizontalStackLayout>
                        <ImageButton Source="edit.png"
                                     BackgroundColor="Transparent"
                                     Grid.Column="1"
                                     Grid.RowSpan="3"
                                     MinimumHeightRequest="24"
                                     MaximumHeightRequest="24"
                                     MinimumWidthRequest="24"
                                     MaximumWidthRequest="24"
                                     HeightRequest="16"
                                     WidthRequest="16"
                                     x:DataType="mv:IndirizzoImpiegatoModelView"
                                     Command="{Binding EditItemCommand,Source={RelativeSource AncestorType={x:Type mod:IndirizzoImpiegatoViewModel}},x:DataType=mod:IndirizzoImpiegatoViewModel}"
                                     CommandParameter="{Binding}"
                                     HorizontalOptions="End" />
                        <ImageButton Source="delete.png"
                                     BackgroundColor="Transparent"
                                     Grid.Column="2"
                                     Grid.RowSpan="3"
                                     MinimumHeightRequest="24"
                                     MinimumWidthRequest="24"
                                     HeightRequest="24"
                                         Command="{Binding DeleteItemCommand,Source={RelativeSource AncestorType={x:Type mod:IndirizzoImpiegatoViewModel}},x:DataType=mod:IndirizzoImpiegatoViewModel}"
                                     HorizontalOptions="End"
                                     CommandParameter="{Binding}" />
                        <Label Grid.Row="2"
                               Text="{Binding Nazione}" />
                    </Grid>

                </Border>
                    
                </DataTemplate>
            </BindableLayout.ItemTemplate>
        </FlexLayout>
    </Grid>
</ContentView>

我只使用一个包含 syncfusion 选项卡控件的页面。tabitems 包含 contentviews。

我不明白背后的代码如何影响网格控制基础的功能。

谢谢

maui
  • 1 个回答
  • 52 Views
Martin Hope
GBM
Asked: 2025-02-27 00:01:35 +0800 CST

.Net Maui App 条形图意外抛出 XLS0414 错误

  • 5

我正在开发 Maui 应用程序并想添加图表,因此我安装了 Syncfusion.Maui.Charts NuGet 包。问题是,在代码隐藏中,我在定义图表的框架中收到以下错误;

Severity    Code    Description Project File    Line    Suppression State
Error (active)  XFC0000 Cannot resolve type "clr-namespace:Syncfusion.Maui.Charts;assembly=Syncfusion.Maui.Charts:sfChart:BarSeries".   MauiApp1 (net8.0-android), MauiApp1 (net8.0-ios), MauiApp1 (net8.0-maccatalyst), MauiApp1 (net8.0-windows10.0.19041.0)  C:\Users\44751\source\repos\MauiApp1\MainPage.xaml  24  
Error   XLS0414 The type 'sfChart:BarSeries' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built.   MauiApp1    C:\Users\44751\source\repos\MauiApp1\MainPage.xaml  24  

我可以确认该包确实出现在解决方案资源管理器中的依赖项下,并尝试卸载/重新安装并删除 bin 和 object 文件夹并更改命名空间,但尽管一切看起来都很好,但似乎没有任何效果。我决定做基础工作,创建一个新的简单项目并安装 Syncfusion.Maui.Charts 包,但尽管我保持了它的简单性,但还是出现了同样的问题。以下是MainPage.xaml.cs;

using Syncfusion.Maui.Charts;
using Syncfusion.Maui.Core.Hosting;


namespace MauiApp1
{
    public partial class MainPage : ContentPage
    {
        public ObservableCollection<SalesData> SalesDataCollection { get; set; }

        public MainPage()
        {
            InitializeComponent();
            SalesDataCollection = new ObservableCollection<SalesData>
                {
                    new SalesData("Product A", 120),
                    new SalesData("Product B", 180),
                    new SalesData("Product C", 90),
                };

            BindingContext = this; // ✅ Set BindingContext
        }


    }

}

以下是MainPage.xaml;

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:sfChart="clr-namespace:Syncfusion.Maui.Charts;assembly=Syncfusion.Maui.Charts"
             x:Class="MauiApp1.MainPage">

    <VerticalStackLayout Padding="20">

        <Label Text="Syncfusion Chart Test" 
               FontSize="24" 
               HorizontalOptions="Center" 
               VerticalOptions="Start" />

        <sfChart:SfCartesianChart HorizontalOptions="FillAndExpand"
                                  VerticalOptions="FillAndExpand">
            <sfChart:SfCartesianChart.XAxes>
                <sfChart:CategoryAxis Title="Products"/>
            </sfChart:SfCartesianChart.XAxes>

            <sfChart:SfCartesianChart.YAxes>
                <sfChart:NumericalAxis Title="Sales"/>
            </sfChart:SfCartesianChart.YAxes>

            <sfChart:SfCartesianChart.Series>
                <sfChart:BarSeries ItemsSource="{Binding SalesDataCollection}"
                                   XBindingPath="ProductName"
                                   YBindingPath="SalesAmount"
                                   ShowDataLabels="True"/>
            </sfChart:SfCartesianChart.Series>

        </sfChart:SfCartesianChart>
    </VerticalStackLayout>

</ContentPage>

错误发生在 .xaml 的第 24 行,即<sfChart:BarSeries ItemsSource="{Binding SalesDataCollection}“sfChart:BarSeries”部分中的“ ”。

MauiProgram.cs 文件如下所示;

using Microsoft.Extensions.Logging;
using Syncfusion.Maui.Core.Hosting;

namespace MauiApp1
{
    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .ConfigureSyncfusionCore()  // ✅ Ensure this line is added
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                    fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
                });
            //builder.ConfigureSyncfusionCore(); // ✅ Register Syncfusion

#if DEBUG
            builder.Logging.AddDebug();
#endif

            return builder.Build();
        }
    }
}

作为参考,MauiApp1.csproj 文件如下所示;

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFrameworks>net8.0-android;net8.0-ios;net8.0-maccatalyst;</TargetFrameworks>
        <TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net8.0-windows10.0.19041.0</TargetFrameworks>
        <!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
        <!-- <TargetFrameworks>$(TargetFrameworks);net8.0-tizen</TargetFrameworks> -->

        <!-- Note for MacCatalyst:
        The default runtime is maccatalyst-x64, except in Release config, in which case the default is maccatalyst-x64;maccatalyst-arm64.
        When specifying both architectures, use the plural <RuntimeIdentifiers> instead of the singular <RuntimeIdentifier>.
        The Mac App Store will NOT accept apps with ONLY maccatalyst-arm64 indicated;
        either BOTH runtimes must be indicated or ONLY macatalyst-x64. -->
        <!-- For example: <RuntimeIdentifiers>maccatalyst-x64;maccatalyst-arm64</RuntimeIdentifiers> -->

        <OutputType>Exe</OutputType>
        <RootNamespace>MauiApp1</RootNamespace>
        <UseMaui>true</UseMaui>
        <SingleProject>true</SingleProject>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>

        <!-- Display name -->
        <ApplicationTitle>MauiApp1</ApplicationTitle>

        <!-- App Identifier -->
        <ApplicationId>com.companyname.mauiapp1</ApplicationId>

        <!-- Versions -->
        <ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
        <ApplicationVersion>1</ApplicationVersion>

        <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">11.0</SupportedOSPlatformVersion>
        <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">13.1</SupportedOSPlatformVersion>
        <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
        <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
        <TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
        <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
    </PropertyGroup>

    <ItemGroup>
        <!-- App Icon -->
        <MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />

        <!-- Splash Screen -->
        <MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128" />

        <!-- Images -->
        <MauiImage Include="Resources\Images\*" />
        <MauiImage Update="Resources\Images\dotnet_bot.png" Resize="True" BaseSize="300,185" />

        <!-- Custom Fonts -->
        <MauiFont Include="Resources\Fonts\*" />

        <!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
        <MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
    </ItemGroup>

    <ItemGroup>
        <PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)" />
        <PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="$(MauiVersion)" />
        <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
        <PackageReference Include="Syncfusion.Maui.Charts" Version="28.2.7" />
    </ItemGroup>



</Project>

我完全搞不懂为什么会收到此错误。我已附上解决方案资源管理器中依赖项的屏幕截图,并可以确认包名称出现在每个 .net8.0 的“包”节点下; 依赖项截图

maui
  • 1 个回答
  • 43 Views
Martin Hope
raV720
Asked: 2025-02-25 22:35:09 +0800 CST

如何在 LiveCharts2、MAUI 中以 XAML 创建轴

  • 5

我想在 MAUI 中在 XAML 下创建 Axis。但是此代码:

<lvc:CartesianChart>
    <lvc:CartesianChart.YAxes>
        <lvcs:Axis Name="Y axis">
        </lvcs:Axis>
    </lvc:CartesianChart.YAxes>
</lvc:CartesianChart>

给了我一个错误:

No property, BindableProperty, or event found for "YAxes", or mismatching type between value and property.

添加的命名空间:

xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.Maui;assembly=LiveChartsCore.SkiaSharpView.Maui"
xmlns:lvcs="clr-namespace:LiveChartsCore.SkiaSharpView;assembly=LiveChartsCore.SkiaSharpView"

我错过了什么?有可能吗?我还没有找到任何通过 XAML 创建轴的示例。

maui
  • 1 个回答
  • 29 Views
Martin Hope
LarryDev
Asked: 2025-02-12 01:50:07 +0800 CST

Maui Entry Horizo​​ntalTextAlignment=当文本大于输入字段且在 Android 上 IsReadOnly=true 时,开始不左对齐文本

  • 5

我遇到过这种情况:我有几个 Entry 控件,这些控件上的文本经常超出输入控件的显示范围。我试图保持文本左对齐,因此我使用 Horizo​​ntalTextAlighnment="Start",当 IsReadOnly="False" 时它将正确显示,但如果我将 Entry 设置为 IsReadOnly="True",则输入字段中的文本将右对齐。

这是一个演示该问题的简单 xaml 页面:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="MauiBugExample.MainPage">
<ScrollView>
    <VerticalStackLayout x:Name="PageVerticalStackLayout"
        Padding="30,0"
        Spacing="25">

        <Label Text="HorizontalTextAlignment=Start IsReadonly=False" />
        <Entry 
            HorizontalTextAlignment="Start" 
            HorizontalOptions="FillAndExpand" 
            Text="abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" 
            IsReadOnly="False"/>
        <Label Text="HorizontalTextAlignment=Start IsReadonly=True" />
        <Entry 
            HorizontalTextAlignment="Start" 
            HorizontalOptions="FillAndExpand" 
            Text="abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" 
            IsReadOnly="True"/>
    </VerticalStackLayout>
</ScrollView>

输出结果如下。第一行非只读,但正确左对齐;第二行只读,但应左对齐,但右对齐:

在此处输入图片描述

仅当文本超出控件大小时才会出现问题。如果我在输入字段中输入的文本较少,即使 ReadOnly=True,它也会保持左对齐

在此处输入图片描述

maui
  • 1 个回答
  • 33 Views
Martin Hope
Kasper Sommer
Asked: 2025-01-23 00:13:19 +0800 CST

MAUI ObservableCollection 未触发转换器

  • 7

我有一个字符串的 ObservableCollection:

public ObservableCollection<string> ChallengePartImageURLs { get; } = new ObservableCollection<string>();

像这样填充/更新:

ChallengePartImageURLs.Clear();
foreach(var url in SelectedChallengePart.ImageURLs) {
    ChallengePartImageURLs.Add(url);
}

UI 更新得很好,但是当集合发生变化时,转换器不会被触发:

IsVisible="{Binding ChallengePartImageURLs, Converter={StaticResource AnyImageCheckConverter}}"

转换器正在工作,因为如果我将 ObservableCollection 更改为 ObservableProperty,它就会被完美触发。

我已尝试将 Binding 包含到 ObservableProperty 的 ConverterParameter 中,但仍然没有触发。

我是否遗漏了什么或者有没有办法触发转换器?

更新

该转换器在 XAML 中声明:

<ContentPage.Resources>
        <ResourceDictionary>
            <converters:AnyImageCheckConverter x:Key="AnyImageCheckConverter"/>
        </ResourceDictionary>
</ContentPage.Resources>

用过的:

<CollectionView ItemsSource="{Binding ChallengePartImageURLs}" IsVisible="{Binding ChallengePartImageURLs, Converter={StaticResource AnyImageCheckConverter}}">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Label Text="{Binding .}" />
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

转换器本身:

{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        try
        {
            if (value != null)
            {
                var list = (ObservableCollection<string>)value;
                if (list.Count > 0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            return false;
        }
        catch (Exception ex)
        {
        }
        return false;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

仅通过清除收藏品并添加新物品才能更改收藏品。

maui
  • 2 个回答
  • 50 Views
Martin Hope
Matthew Pans
Asked: 2025-01-19 20:16:20 +0800 CST

Plugin.InAppBilling:确认 Android 购买

  • 6

我Plugin.InAppBilling在我的 MAUI 应用程序中使用它进行订阅。对于 Android 部分,我需要在成功购买后进行确认。

选项 1:ConsumePurchaseAsync

if (DeviceInfo.Platform == DevicePlatform.Android)
{
    var consumed = await CrossInAppBilling.Current.ConsumePurchaseAsync(productId, purchase.PurchaseToken);
    if (!consumed)
    {
        Debug.WriteLine("Purchase consumption/acknowledgment failed");
        return;
    }
    Debug.WriteLine("Purchase acknowledged successfully");
}

但我遇到了以下异常:

16:05:10:848    [0:] purchaseEx:>>Plugin.InAppBilling.InAppBillingPurchaseException: Unable to process purchase.
16:05:10:848       at Plugin.InAppBilling.InAppBillingImplementation.ParseBillingResult(BillingResult result, Boolean ignoreInvalidProducts)
16:05:10:848       at Plugin.InAppBilling.InAppBillingImplementation.ConsumePurchaseAsync(String productId, String transactionIdentifier)
16:05:10:848       at MyProjectName.Pages.ListPlansPage.PlanClicked(Object sender, EventArgs e) in E:\My Projects\MAUI
16:05:10:848    eedhelp-app-maui\MyProjectName\Pages\Subscription\ListPlansPage.xaml.cs:line 371
16:05:10:909    The thread 25 has exited with code 0 (0x0).

以下行存在异常:

var consumed = await CrossInAppBilling.Current.ConsumePurchaseAsync(productId, purchase.PurchaseToken);

选项 2:DependencyService

创建了一个接口:IPurchaseAcknowledgment

public interface IPurchaseAcknowledgment
{
    Task<bool> AcknowledgePurchaseAsync(string purchaseToken);
}

实施IPurchaseAcknowledgment日期MainActivity:

public class MainActivity : MauiAppCompatActivity, IPurchaseAcknowledgment
{
    /// <summary>
    /// Acknowledge purchase using Google Play BillingClient
    /// </summary>
    public async Task<bool> AcknowledgePurchaseAsync(string purchaseToken)
    {
        var billingClient = BillingClient.NewBuilder(Android.App.Application.Context)
            .SetListener(new PurchaseUpdateListener()) // You can implement your own listener if needed
            .EnablePendingPurchases()
            .Build();

        // Connect to the BillingClient
        var billingConnectionTaskCompletionSource = new TaskCompletionSource<BillingResult>();
        billingClient.StartConnection(new BillingClientStateListener(
            onBillingSetupFinished: billingResult => billingConnectionTaskCompletionSource.SetResult(billingResult),
            onBillingServiceDisconnected: () => billingConnectionTaskCompletionSource.SetException(new System.Exception("Billing service disconnected"))
        ));

        var connectionResult = await billingConnectionTaskCompletionSource.Task;
        if (connectionResult.ResponseCode != BillingResponseCode.Ok)
        {
            return false; // Connection failed
        }

        // Acknowledge the purchase
        var acknowledgeParams = AcknowledgePurchaseParams.NewBuilder()
            .SetPurchaseToken(purchaseToken)
            .Build();

        var acknowledgeTaskCompletionSource = new TaskCompletionSource<BillingResult>();
        billingClient.AcknowledgePurchase(acknowledgeParams, new AcknowledgePurchaseResponseListener(
            result => acknowledgeTaskCompletionSource.SetResult(result)
        ));

        var acknowledgeResult = await acknowledgeTaskCompletionSource.Task;

        // End connection
        billingClient.EndConnection();

        return acknowledgeResult.ResponseCode == BillingResponseCode.Ok;
    }

    /// <summary>
    /// Listener for purchase updates (can be extended if required)
    /// </summary>
    private class PurchaseUpdateListener : Java.Lang.Object, IPurchasesUpdatedListener
    {
        public void OnPurchasesUpdated(BillingResult billingResult, IList<Purchase> purchases)
        {
            // Handle purchase updates here if needed
        }
    }

    /// <summary>
    /// Listener for billing client state
    /// </summary>
    private class BillingClientStateListener : Java.Lang.Object, IBillingClientStateListener
    {
        private readonly System.Action<BillingResult> onBillingSetupFinished;
        private readonly System.Action onBillingServiceDisconnected;

        public BillingClientStateListener(System.Action<BillingResult> onBillingSetupFinished, System.Action onBillingServiceDisconnected)
        {
            this.onBillingSetupFinished = onBillingSetupFinished;
            this.onBillingServiceDisconnected = onBillingServiceDisconnected;
        }

        public void OnBillingSetupFinished(BillingResult billingResult)
        {
            onBillingSetupFinished?.Invoke(billingResult);
        }

        public void OnBillingServiceDisconnected()
        {
            onBillingServiceDisconnected?.Invoke();
        }
    }

    /// <summary>
    /// Listener for acknowledge purchase response
    /// </summary>
    private class AcknowledgePurchaseResponseListener : Java.Lang.Object, IAcknowledgePurchaseResponseListener
    {
        private readonly System.Action<BillingResult> onAcknowledgeResponse;

        public AcknowledgePurchaseResponseListener(System.Action<BillingResult> onAcknowledgeResponse)
        {
            this.onAcknowledgeResponse = onAcknowledgeResponse;
        }

        public void OnAcknowledgePurchaseResponse(BillingResult billingResult)
        {
            onAcknowledgeResponse?.Invoke(billingResult);
        }
    }
}

购买计划后最终结果:

if (DeviceInfo.Platform == DevicePlatform.Android)
{
    var acknowledgmentService = DependencyService.Get<IPurchaseAcknowledgment>();
    var acknowledged = await acknowledgmentService.AcknowledgePurchaseAsync(purchase.PurchaseToken);

    if (!acknowledged)
    {
        Debug.WriteLine("Purchase acknowledgment failed");
        return;
    }
    Debug.WriteLine("Purchase acknowledged successfully");
}

但出现以下异常:

16:23:24:835    [0:] exception:>>System.NullReferenceException: Object reference not set to an instance of an object.
16:23:24:835       at MyProjectName.Pages.ListPlansPage.PlanClicked(Object sender, EventArgs e) in E:\My Projects\MAUI
16:23:24:835    eedhelp-app-maui\MyProjectName\Pages\Subscription\ListPlansPage.xaml.cs:line 383

以下行存在异常:

var acknowledged = await acknowledgmentService.AcknowledgePurchaseAsync(purchase.PurchaseToken);

还有其他解决办法吗?

更新

我尝试如下:

var consumed = await CrossInAppBilling.Current.ConsumePurchaseAsync(purchase.ProductId, purchase.TransactionIdentifier);

但出现以下异常:

12:43:02:766    [0:] purchaseEx:>>Plugin.InAppBilling.InAppBillingPurchaseException: Unable to process purchase.
12:43:02:766       at Plugin.InAppBilling.InAppBillingImplementation.ParseBillingResult(BillingResult result, Boolean ignoreInvalidProducts)
12:43:02:766       at Plugin.InAppBilling.InAppBillingImplementation.ConsumePurchaseAsync(String productId, String transactionIdentifier)
12:43:02:766       at MyProjectName.Pages.ListPlansPage.PlanClicked(Object sender, EventArgs e) in E:\My Projects\MAUI
12:43:02:766    eedhelp-app-maui\MyProjectName\Pages\Subscription\ListPlansPage.xaml.cs:line 372
maui
  • 1 个回答
  • 44 Views
Martin Hope
Nico
Asked: 2025-01-19 17:38:50 +0800 CST

如何更改 .NET MAUI ContentPage 的基类?

  • 6

假设我的所有页面都有一些通用实用程序,因此我想抽象出一个基类,供所有内容页面派生。问题是,新创建的内容页面自然定义为部分,我不能简单地更改代码隐藏部分以使用新的基类。编译器会抱怨:'NewPage1' 的部分声明不能指定不同的基类 CS0263。

maui
  • 1 个回答
  • 23 Views
Martin Hope
Matthew Pans
Asked: 2025-01-08 21:22:11 +0800 CST

MAUI:如何在发布模式下查看调试语句

  • 5

我正在尝试在发布模式下打印调试器语句来解决一个问题。

为此我做了以下改变:

1 在.csproj 文件上添加了 DebugType、DebugSymbols、Debuggable 和 AndroidEnableDeveloperInstrumentation。

<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net8.0-android|AnyCPU'">
  <ApplicationId>com.companyname.appname</ApplicationId>
  <AndroidPackageFormat>apk</AndroidPackageFormat>
  <ApplicationTitle>appname</ApplicationTitle>
  <DebugType>portable</DebugType>
  <DebugSymbols>true</DebugSymbols>
  <Debuggable>true</Debuggable>
  <AndroidEnableDeveloperInstrumentation>true</AndroidEnableDeveloperInstrumentation>
</PropertyGroup>

2 在应用程序下的android manifext文件中添加android:debuggable="true"。

3 在MAUIProgram.cs中添加以下代码。

builder.Logging.AddConsole(options =>
{
    options.IncludeScopes = true;
});
builder.Logging.SetMinimumLevel(LogLevel.Debug);
  1. 在 App.xaml.cs 下添加以下代码。

    使用 Microsoft.Extensions.Logging;

    公共部分类 App:应用程序 { 公共 App(ILogger logger) { InitializeComponent();

         logger.LogInformation("App started in production mode.");
         logger.LogError("An error occurred.");
     }
    

    }

  2. 在项目属性下启用开发人员工具以进行发布模式。

在此处输入图片描述

但是当我在发布模式下运行时,我看到的是以下屏幕。

在此处输入图片描述

在发布模式下查看调试器语句还有其他变化吗?

maui
  • 1 个回答
  • 34 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    重新格式化数字,在固定位置插入分隔符

    • 6 个回答
  • Marko Smith

    为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会?

    • 2 个回答
  • Marko Smith

    VScode 自动卸载扩展的问题(Material 主题)

    • 2 个回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Martin Hope
    Fantastic Mr Fox msvc std::vector 实现中仅不接受可复制类型 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant 使用 chrono 查找下一个工作日 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor 构造函数的成员初始化程序可以包含另一个成员的初始化吗? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský 为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul C++20 是否进行了更改,允许从已知绑定数组“type(&)[N]”转换为未知绑定数组“type(&)[]”? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann 为什么 {2,3,10} 和 {x,3,10} (x=2) 的顺序不同? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve