提问人:okanalagas 提问时间:9/11/2023 最后编辑:okanalagas 更新时间:9/12/2023 访问量:109
在哪里执行内容视图业务逻辑操作
Where to do Content View Bussiness Logic Operations
问:
我正在开发一个 .net maui 应用程序,我需要在我的自定义控件中获取和设置数据。
目标是:
页面:
<ContentPage
x:Class="V7.UIS.MauiMobile.Views.AboutPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:V7.UIS.MauiMobile.Controls.Views"
xmlns:viewmodel="clr-namespace:V7.UIS.MauiMobile.ViewModels"
Title="About"
ios:Page.UseSafeArea="true"
x:DataType="viewmodel:AboutViewModel"
BackgroundColor="{StaticResource NormalBackgroundColor}">
<VerticalStackLayout>
<controls:ItemBarcodeSearchView />
<Entry Text="Count" />
<Button
Grid.Row="1"
Grid.Column="1"
Command="{Binding AddCommand}"
Text="Add" />
</VerticalStackLayout>
</ContentPage>
自定义控件 xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentView
x:Class="V7.UIS.MauiMobile.Controls.Views.ItemBarcodeSearchView"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:dxe="clr-namespace:DevExpress.Maui.Editors;assembly=DevExpress.Maui.Editors"
x:Name="BarcodeSearchView">
<ContentView.ControlTemplate>
<ControlTemplate>
<VerticalStackLayout>
<Grid
x:Name="ButtonGrid"
Margin="5"
IsVisible="{TemplateBinding IsVisibleButtonGrid}">
<Button Clicked="ShowView" Text="Enter Barcode" />
</Grid>
<Grid
x:Name="DetailGrid"
Padding="15"
ColumnDefinitions="*"
ColumnSpacing="20"
IsVisible="{TemplateBinding IsVisibleDetailGrid}"
RowDefinitions="Auto,Auto"
VerticalOptions="Center">
<dxe:TextEdit
Grid.Row="0"
Margin="0"
ClearIconCommand="{TemplateBinding ClearFieldsCommand}"
ClearIconVisibility="Always"
LabelText="Barcode"
Text="{TemplateBinding Barcode}" />
<dxe:TextEdit
Grid.Row="1"
Margin="0"
ClearIconVisibility="Never"
LabelText="Item"
Text="{TemplateBinding ItemDescription}" />
<Button
Grid.Row="6"
Margin="0,10,0,0"
Command="{Binding Source={x:Reference BarcodeSearchView}, Path=Search}"
Text="Search" />
<Button
Grid.Row="7"
Margin="0,10,0,0"
Clicked="SendBarcodeDetails"
Text="Ok" />
</Grid>
</VerticalStackLayout>
</ControlTemplate>
</ContentView.ControlTemplate>
</ContentView>
当我按下搜索按钮时,我想执行此命令以设置项目描述。这是该内容视图的业务逻辑,我不想一遍又一遍地重复此代码。
private readonly HttpClient _client;
public blabla(IHttpClientFactory factory)
{
_client = factory?.CreateClient(AppConstants.ApiName);
}
GetBarcodeDetailQuery query = new()
{
Barcode = barcode
};
await client.GetDataFromApi<GetBarcodeDetailQuery, GetBarcodeDetailViewModel>("Cards/ItemBarcode/GetBarcodeDetail", query, FindBarcodeCallBack);
我应该在哪里放置此操作以及如何放置此操作?我一个星期都想不通。
自定义控件 xaml.cs :
using CommunityToolkit.Mvvm.Input;
using V7.UIS.MauiMobile.Models;
namespace V7.UIS.MauiMobile.Controls.Views;
public partial class ItemBarcodeSearchView : ContentView
{
public ItemBarcodeSearchView()
{
InitializeComponent();
IsVisibleButtonGrid = "true";
IsVisibleDetailGrid = "false";
}
public event EventHandler<ItemBarcodeDetail> BarcodeDetailsReady;
public static readonly BindableProperty BarcodeProperty =
BindableProperty.Create(nameof(Barcode), typeof(string), typeof(ItemBarcodeSearchView));
public static readonly BindableProperty ItemDescriptionProperty =
BindableProperty.Create(nameof(ItemDescription), typeof(string), typeof(ItemBarcodeSearchView));
public static readonly BindableProperty IsVisibleButtonGridProperty =
BindableProperty.Create(nameof(IsVisibleButtonGrid), typeof(string), typeof(ItemBarcodeSearchView));
public static readonly BindableProperty IsVisibleDetailGridProperty =
BindableProperty.Create(nameof(IsVisibleDetailGrid), typeof(string), typeof(ItemBarcodeSearchView));
public static readonly BindableProperty SearchProperty =
BindableProperty.Create(nameof(Search), typeof(RelayCommand), typeof(ItemBarcodeSearchView));
public RelayCommand Search
{
get => (RelayCommand)GetValue(SearchProperty);
set => SetValue(SearchProperty, value);
}
public string IsVisibleButtonGrid
{
get => (string)GetValue(IsVisibleButtonGridProperty);
set => SetValue(IsVisibleButtonGridProperty, value);
}
public string IsVisibleDetailGrid
{
get => (string)GetValue(IsVisibleDetailGridProperty);
set => SetValue(IsVisibleDetailGridProperty, value);
}
public string Barcode
{
get => (string)GetValue(BarcodeProperty);
set => SetValue(BarcodeProperty, value);
}
public string ItemDescription
{
get => (string)GetValue(ItemDescriptionProperty);
set => SetValue(ItemDescriptionProperty, value);
}
[RelayCommand]
public void ClearFields()
{
Barcode = string.Empty;
ItemDescription = string.Empty;
}
private void SendBarcodeDetails(object sender, EventArgs e)
{
ItemBarcodeDetail itemBarcodeDetail = new()
{
Barcode = Barcode,
ItemDescription = ItemDescription
};
BarcodeDetailsReady?.Invoke(sender, itemBarcodeDetail);
IsVisibleButtonGrid = "true";
IsVisibleDetailGrid = "false";
}
private void ShowView(object sender, EventArgs e)
{
IsVisibleButtonGrid = "false";
IsVisibleDetailGrid = "true";
}
}
希望这里有人能帮助我。
答:
0赞
Jessie Zhang -MSFT
9/11/2023
#1
该类定义一个 View 类型的 Content 属性,该属性表示 .此属性由对象支持,这意味着它可以是数据绑定的目标,并设置样式。ContentView
ContentView
BindableProperty
ContentView 类本身提供的功能很少,但可用于创建自定义控件。创建自定义控件的过程是:
- 创建一个派生自 ContentView 类的类。
- 在代码隐藏文件中定义任何控件属性或事件 自定义控件。
- 定义自定义控件的 UI。
有关详细信息,您可以查看官方文档:创建自定义控件。
注意:
您还可以在此处查看示例:ContentView 演示,它将帮助您了解如何使用 创建自定义控件。尽管此示例是 Xamarin 窗体的应用,但它也适用于 MAUI。ContentView
评论
0赞
okanalagas
9/11/2023
我可以在自定义控件中使用 httpclientfactory 等服务吗?对于重复操作是否最好这样做
0赞
Jessie Zhang -MSFT
9/11/2023
ContentView
是用于显示各种 UI 的控件,并且是可重用的。对于 service 之类的代码,我们一般不建议将其添加到 .我们经常使用 MVVM 实现,经常将服务请求等代码放在 ViewModel 中。有关 MVVM 的更多信息,可以查看文档模型-视图-视图模型模式。httpclient
ContentView
0赞
Jessie Zhang -MSFT
9/12/2023
嗨,@Okanalagas,我们通常为页面设置 t 而不是 customview(例如)。您可以将 添加到页面的 ViewModel 中,并在页面的 ViewModel 中请求数据。关于这一点,有一些类似的线程,你可以在这里检查它们:线程 1 和线程 2。BindContext
ItemBarcodeSearchView
HttpClient
0赞
okanalagas
9/12/2023
感谢您的回答,但我仍然想问这个问题。我想在多个地方使用此组件。这种方法不会导致代码重复吗?
0赞
Jessie Zhang -MSFT
9/12/2023
是的,自定义控件本身可以重用。我们只需要向它传递必要的参数。
0赞
okanalagas
9/12/2023
#2
我做了这样的事情,它有效,但使用我不确定是最佳做法。
这是页面:
<ContentPage
xmlns:viewmodel="clr-namespace:V7.UIS.MauiMobile.ViewModels"
x:DataType="viewmodel:AboutViewModel"
Title="About">
<VerticalStackLayout>
<controls:ItemBarcodeSearchView HttpClient="{Binding HttpClient}" />
<Entry Text="Count" />
<Button
Grid.Row="1"
Grid.Column="1"
Text="Add"/>
</VerticalStackLayout>
</ContentPage>
using V7.UIS.MauiMobile.Constants;
namespace V7.UIS.MauiMobile.ViewModels
{
public class AboutViewModel : BaseViewModel
{
private readonly HttpClient _client;
public const string ViewName = "AboutPage";
public AboutViewModel(IHttpClientFactory factory)
{
Title = "About";
_client = factory?.CreateClient(AppConstants.ApiName);
}
public HttpClient HttpClient => _client;
}
}
下面是自定义控件:
using CommunityToolkit.Mvvm.Input;
using V7.BaseApplication.AppModels.Erp.Cards.Item.ItemBarcode.Queries;
using V7.BaseApplication.AppModels.Erp.Cards.Item.ItemBarcode.ViewModel;
using V7.UIS.MauiMobile.Helpers;
using V7.UIS.MauiMobile.Models;
namespace V7.UIS.MauiMobile.Controls.Views;
public partial class ItemBarcodeSearchView : ContentView
{
public ItemBarcodeSearchView()
{
InitializeComponent();
IsVisibleButtonGrid = "true";
IsVisibleDetailGrid = "false";
}
public event EventHandler<ItemBarcodeDetail> BarcodeDetailsReady;
#region PropertyDefinition
public static readonly BindableProperty BarcodeProperty =
BindableProperty.Create(nameof(Barcode), typeof(string), typeof(ItemBarcodeSearchView));
public static readonly BindableProperty ItemDescriptionProperty =
BindableProperty.Create(nameof(ItemDescription), typeof(string), typeof(ItemBarcodeSearchView));
public static readonly BindableProperty ItemUnitProperty =
BindableProperty.Create(nameof(ItemUnit), typeof(string), typeof(ItemBarcodeSearchView));
public static readonly BindableProperty ItemLotProperty =
BindableProperty.Create(nameof(ItemLot), typeof(string), typeof(ItemBarcodeSearchView));
public static readonly BindableProperty ItemSerialNumberProperty =
BindableProperty.Create(nameof(ItemSerialNumber), typeof(string), typeof(ItemBarcodeSearchView));
public static readonly BindableProperty QuantityProperty =
BindableProperty.Create(nameof(Quantity), typeof(string), typeof(ItemBarcodeSearchView));
public static readonly BindableProperty IsVisibleButtonGridProperty =
BindableProperty.Create(nameof(IsVisibleButtonGrid), typeof(string), typeof(ItemBarcodeSearchView));
public static readonly BindableProperty IsVisibleDetailGridProperty =
BindableProperty.Create(nameof(IsVisibleDetailGrid), typeof(string), typeof(ItemBarcodeSearchView));
public static readonly BindableProperty HttpClientProperty =
BindableProperty.Create(nameof(HttpClient), typeof(HttpClient), typeof(ItemBarcodeSearchView));
public HttpClient HttpClient
{
get => (HttpClient)GetValue(HttpClientProperty);
set => SetValue(HttpClientProperty, value);
}
public string IsVisibleButtonGrid
{
get => (string)GetValue(IsVisibleButtonGridProperty);
set => SetValue(IsVisibleButtonGridProperty, value);
}
public string IsVisibleDetailGrid
{
get => (string)GetValue(IsVisibleDetailGridProperty);
set => SetValue(IsVisibleDetailGridProperty, value);
}
public string Barcode
{
get => (string)GetValue(BarcodeProperty);
set => SetValue(BarcodeProperty, value);
}
public string ItemDescription
{
get => (string)GetValue(ItemDescriptionProperty);
set => SetValue(ItemDescriptionProperty, value);
}
public string ItemUnit
{
get => (string)GetValue(ItemUnitProperty);
set => SetValue(ItemUnitProperty, value);
}
public string ItemLot
{
get => (string)GetValue(ItemLotProperty);
set => SetValue(ItemLotProperty, value);
}
public string ItemSerialNumber
{
get => (string)GetValue(ItemSerialNumberProperty);
set => SetValue(ItemSerialNumberProperty, value);
}
public string Quantity
{
get => (string)GetValue(QuantityProperty);
set => SetValue(QuantityProperty, value);
}
#endregion
private void ShowView(object sender, EventArgs e)
{
IsVisibleButtonGrid = "false";
IsVisibleDetailGrid = "true";
}
[RelayCommand]
public void ClearFields()
{
Barcode = string.Empty;
ItemDescription = string.Empty;
ItemUnit = string.Empty;
ItemLot = string.Empty;
ItemSerialNumber = string.Empty;
Quantity = string.Empty;
}
[RelayCommand]
public async Task Search()
{
await FindItemDetails(Barcode, HttpClient);
}
public async Task FindItemDetails(string barcode, HttpClient client)
{
if (!string.IsNullOrEmpty(barcode))
{
GetBarcodeDetailQuery query = new()
{
Barcode = barcode
};
await client.GetDataFromApi<GetBarcodeDetailQuery, GetBarcodeDetailViewModel>("Cards/ItemBarcode/GetBarcodeDetail", query, FindBarcodeCallBack);
}
else
{
await Shell.Current.DisplayAlert("Hata", "Lütfen bir barkod giriniz.", "Ok");
}
}
void FindBarcodeCallBack(GetBarcodeDetailViewModel vm)
{
ItemDescription = vm.Item.Description;
ItemUnit = vm.ItemUnits.FirstOrDefault().ToString();
ItemLot = vm.Lot.ToString();
ItemSerialNumber = vm.SerialNumber.ToString();
Quantity = "0";
}
private void SendBarcodeDetails(object sender, EventArgs e)
{
ItemBarcodeDetail itemBarcodeDetail = new()
{
Barcode = Barcode,
ItemDescription = ItemDescription,
ItemUnit = ItemUnit,
ItemLot = ItemLot,
ItemSerialNumber = ItemSerialNumber,
Quantity = Quantity,
};
BarcodeDetailsReady?.Invoke(sender, itemBarcodeDetail);
IsVisibleButtonGrid = "true";
IsVisibleDetailGrid = "false";
}
}
评论
0赞
Amit Mohanty
9/13/2023
您需要对回复中分享的内容进行说明。
上一个:ASCX 用户控件未显示
下一个:MAUI 自定义控件中的字体
评论