框架代码结构
-
views
程序员创建的用户页面,views文件夹下的每一个xaml对应一个页面
-
App.xaml
定义App类,实例化应用程序
-
AppShell.xaml
生成内容的用户界面,如用户界面是怎么展示的,贴图是什么
Xamarin.Forms
布局
垂直和水平
stackLayout : 垂直方向
<StackLayout Margin="20,35,20,25"> //四周的边界宽度
<Label Text="The StackLayout has its Margin property set, to control the rendering position of the StackLayout." />
<Label Text="The Padding property can be set to specify the distance between the StackLayout and its children." />
<Label Text="The Spacing property can be set to specify the distance between views in the StackLayout." />
</StackLayout>
stackLayout:水平方向
修改stackLayout的声明方式
<StackLayout Margin="20,35,20,25"
Orientation="Horizontal">
<Label Text="The StackLayout has its Margin property set, to control the rendering position of the StackLayout." />
<Label Text="The Padding property can be set to specify the distance between the StackLayout and its children." />
<Label Text="The Spacing property can be set to specify the distance between views in the StackLayout." />
</StackLayout>
控制对齐方式及拓展
<StackLayout Margin="20,35,20,25">
<Label Text="Start"
HorizontalOptions="Start"
BackgroundColor="Gray" />
<Label Text="Center"
HorizontalOptions="Center"
BackgroundColor="Gray" />
<Label Text="End"
HorizontalOptions="End"
BackgroundColor="Gray" />
<Label Text="Fill"
HorizontalOptions="Fill"
BackgroundColor="Gray" />
<Label Text="StartAndExpand"
VerticalOptions="StartAndExpand"
BackgroundColor="Gray" />
<Label Text="CenterAndExpand"
VerticalOptions="CenterAndExpand"
BackgroundColor="Gray" />
<Label Text="EndAndExpand"
VerticalOptions="EndAndExpand"
BackgroundColor="Gray" />
<Label Text="FillAndExpand"
VerticalOptions="FillAndExpand"
BackgroundColor="Gray" />
</StackLayout>
HorizontalOption是控制对齐方式
VerticalOptions是在HorizontalOption的基础上做拓展
对于垂直对齐方式,每个 Label
在 StackLayout
内占据相同的空间量(值垂直方向的空间量)。 但是,只有最后一个 Label
(可将 VerticalOptions
属性设置为 FillAndExpand
)具有不同的大小。
网格
将子组织分为行和列
指定行和列
<Grid Margin="20,35,20,20">
<Grid.ColumnDefinitions> //属性带s,这个属性是ColumnDefinition对象的几何,对象不带s,注意区分
<ColumnDefinition Width="0.5*" /> //带*的是比例,不带的是绝对值
<ColumnDefinition Width="0.5*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Label Text="Column 0, Row 0" />
<Label Grid.Column="1"
Text="Column 1, Row 0" />
<Label Grid.Row="1"
Text="Column 0, Row 1" />
<Label Grid.Column="1"
Grid.Row="1"
Text="Column 1, Row 1" />
</Grid>
利用Grid.RowSpan=“2” 字段可以选择跨行或者跨列
控件
label
属性
<Label Text="Welcome to Xamarin.Forms!"
TextColor="Blue"
FontAttributes="Italic"
FontSize="22"
TextDecorations="Underline"
HorizontalOptions="Center" />
可以利用一些标签来使在一个label中使用多种格式的文本
Button
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ButtonTutorial.MainPage">
<StackLayout Margin="20,35,20,20">
<Button Text="Click me" />
</StackLayout>
</ContentPage>
按钮点击事件
void OnButtonClicked(object sender, EventArgs e)
{
(sender as Button).Text = "Click me again!";
}
sender as Button用于访问Button对象,这个不能省略
条目
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="EntryTutorial.MainPage">
<StackLayout Margin="20,35,20,20">
<Entry Placeholder="Enter text" />
</StackLayout>
</ContentPage>
响应文本更改:
void OnEntryTextChanged(object sender, TextChangedEventArgs e) //当文本更改时候
{
string oldText = e.OldTextValue;
string newText = e.NewTextValue;
}
void OnEntryCompleted(object sender, EventArgs e) //当文本更改完成后
{
string text = ((Entry)sender).Text;
}
自定义行为:
<Entry Placeholder="Enter password"
MaxLength="15"
IsSpellCheckEnabled="false"
IsTextPredictionEnabled="false"
IsPassword="true" /> //对输入的字符进行掩码
编辑器
<Editor Placeholder="Enter multi-line text here"
HeightRequest="200"
TextChanged="OnEditorTextChanged"
Completed="OnEditorCompleted" />
总结:
一般控件都分为这三种特性:
- 怎么创建的
- 怎么响应文本更改
- 自定义行为
图像
<Image Source="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"
Aspect="Fill"
HeightRequest="{OnPlatform iOS=300, Android=250}"
WidthRequest="{OnPlatform iOS=300, Android=250}"
HorizontalOptions="Center" /> //水平居中
显示本地图片
Android端:
将本地图片拖至 Resources/drawable下面
<Image Source="XamarinLogo" //这里直接写图片名称即可,不用带后缀
WidthRequest="{OnPlatform iOS=300, Android=250}"
HorizontalOptions="Center" />
collectview
可进行条目的内容绑定和响应项选择
<CollectionView ItemsSource="{Binding Monkeys}"
SelectionMode="Single"
SelectionChanged="OnSelectionChanged" />
void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
Monkey selectedItem = e.CurrentSelection[0] as Monkey;
}
可以自定义外观,涉及到一些数据绑定的操作,详情参考
弹出窗口
定义弹出窗口按钮
<StackLayout Margin="20,35,20,20">
<Button Text="Display alert"
Clicked="OnDisplayAlertButtonClicked" />
<Button Text="Display alert question"
Clicked="OnDisplayAlertQuestionButtonClicked" />
</StackLayout>
定义弹窗事件:主要是调用调用 DisplayAlert
方法
async void OnDisplayAlertButtonClicked(object sender, EventArgs e)
{
await DisplayAlert("Alert", "This is an alert.", "OK");
}
async void OnDisplayAlertQuestionButtonClicked(object sender, EventArgs e)
{
bool response = await DisplayAlert("Save?", "Would you like to save your data?", "Yes", "No");
Console.WriteLine("Save data: " + response);
}
显示操作工作表
点击按钮 弹出窗体供用户选择
<Button Text="Display action sheet"
Clicked="OnDisplayActionSheetButtonClicked" />
async void OnDisplayActionSheetButtonClicked(object sender, EventArgs e)
{
//这里的null不能省略,返回用户点击的string
string action = await DisplayActionSheet("Send to?", "Cancel", null, "Email", "Twitter", "Facebook");
Console.WriteLine("Action: " + action);
}
生命周期
在APP.xaml.cs中,记录着APP对应的生命周期
- 应用程序启动时调用
OnStart
方法。 - 应用程序转到后台时调用
OnSleep
方法。 - 应用程序从后台恢复时调用
OnResume
方法。
应用:在设备重启的时候,利用在后台保存的数据,重新在设备中加载进来
App.xaml.cs
using System;
using Xamarin.Forms;
namespace AppLifecycleTutorial
{
public partial class App : Application
{
const string displayText = "displayText";
public string DisplayText { get; set; }
public App()
{
InitializeComponent();
MainPage = new MainPage();
}
protected override void OnStart()
{
Console.WriteLine("OnStart");
if (Properties.ContainsKey(displayText))
{
DisplayText = (string)Properties[displayText];
}
}
protected override void OnSleep()
{
Console.WriteLine("OnSleep");
//利用Properties来保存数据,这个字典是会自动保存在Properties上面的
Properties[displayText] = DisplayText;
}
protected override void OnResume()
{
Console.WriteLine("OnResume");
}
}
}
页面代码:
//xaml
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AppLifecycleTutorial.MainPage">
<StackLayout Margin="20,35,20,20">
<Entry x:Name="entry"
Placeholder="Enter text here"
Completed="OnEntryCompleted" />
</StackLayout>
</ContentPage>
//xaml.cs
protected override void OnAppearing() OnAppearing()会在页面加载时候调用
{
base.OnAppearing();
entry.Text = (Application.Current as App).DisplayText;
}
void OnEntryCompleted(object sender, EventArgs e)
{
(Application.Current as App).DisplayText = entry.Text;
}
.Net Core
post请求注意事项
前端向ASP .Net Core Post 类型Api发送请求的时候,接受参数注意
1、如果客户端Content-Type是application/json, api接口如果是用单个对象做参数的时候,加或者不加[FromBody]都可以正常解析参数,但是接口是用对象列表做参数时候,则必须加[FromBody],否则读取不到参数。
2、如果客户端Content-Type不是application/json,api接口必须加[FromForm],否则客户端调用接口会报400错误。
3、如果加上[FromBody],客户端Content-Type不是application/json,接口会报400错误。
总结:
客户端如果提交Json数据时候,都加上[FromBody]
如果客户端提交的数据Content-Type如果不为application/json时,会报错,如果要解决报错,需要在接口上加上[FromForm]。
发送post请求构造json字符串:
var data = new
{
name,
passwd
};
string json = JsonConvert.SerializeObject(data); //json也是一个string 类型
var content = new StringContent(json, Encoding.UTF8, "application/json");
HttpResponseMessage response = await http.PostAsync(uri, content);
解析后端传过来的json字符串:
var content = await response.Content.ReadAsStringAsync();
JObject con = JObject.Parse(content);
string str = con["name"].ToString()
异步与多线程
I/O密集型用异步
c#5.0以上利用async、await语法糖
计算密集型用多线程
进程是资源分配的最小单位,线程是调度的最小单位。
进程的并发需要涉及到很多的上下文切换(保存现场,恢复现场等),需要耗费大量的时间,而相比而言,切换线程所需要的开销更小。
为什么要引入进程和线程
- 提高CPU利用率,在早期的单道批处理系统中,如果执行中的代码需要依赖与外部条件,将会导致CPU空闲,例如文件读取,等待键盘信号输入,这将浪费大量的CPU时间。引入多进程和线程可以解决CPU利用率低这个问题。
- 隔离程序之间的数据(每个进程都有单独的地址空间),保证系统运行的稳定性。
- 提高系统的响应性和交互能力。
模型类中的get、set
模型类的通俗理解:这个类本身是用来作为模型传数的,不做一些逻辑的处理
public class person
{
public string name;
}
public class person
{
public string Name{set;get;}
}
比较这两个类:
第一个类没有对name私有属性进行封装,而第二个类进行了封装,便于对Name属性进行读和写
例如:
private string name;
public string Name
{
get { return name; }
set
{
name = String.IsNullOrEmpty(value) ? "空" : value;
}
}