basic logic

This commit is contained in:
2022-02-25 12:20:16 +08:00
parent abeae1cab9
commit 9a6011c3d8
49 changed files with 773 additions and 73 deletions

View File

@@ -24,6 +24,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Models\BaseModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Models\Billing.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Models\Category.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Models\Account.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Themes\BaseTheme.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Themes\Dark.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Themes\Light.cs" />
@@ -33,10 +34,15 @@
<Compile Include="$(MSBuildThisFileDirectory)UI\BillingPage.cs" />
<Compile Include="$(MSBuildThisFileDirectory)UI\Converters.cs" />
<Compile Include="$(MSBuildThisFileDirectory)UI\CustomControl.cs" />
<Compile Include="$(MSBuildThisFileDirectory)UI\CustomEffect.cs" />
<Compile Include="$(MSBuildThisFileDirectory)UI\Definition.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Views\AccountPage.xaml.cs">
<DependentUpon>AccountPage.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Views\AddAccountPage.xaml.cs">
<DependentUpon>AddAccountPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Views\AddBillPage.xaml.cs">
<DependentUpon>AddBillPage.xaml</DependentUpon>
</Compile>
@@ -73,4 +79,9 @@
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Views\AddAccountPage.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
</Project>

View File

@@ -11,6 +11,20 @@
<Friday>Fr</Friday>
<Saturday>Sa</Saturday>
<NoRecords>Bills not yet generated</NoRecords>
<Memo>Click here to record</Memo>
<TapToMemo>Click here to record</TapToMemo>
<TitleDateFormat>MM/dd/yyyy</TitleDateFormat>
<Balance>Balance</Balance>
<Assets>Assets</Assets>
<Liability>Liability</Liability>
<AddAccount>Add Account</AddAccount>
<AccountName>Account Name</AccountName>
<AccountNamePlaceholder>Please enter account name</AccountNamePlaceholder>
<Icon>Icon</Icon>
<Category>Category</Category>
<Balance>Balance</Balance>
<BalancePlaceholder>Please enter the balance</BalancePlaceholder>
<Currency>Currency</Currency>
<CNY>Chinese Yuan (CNY)</CNY>
<Memo>Note</Memo>
<MemoPlaceholder>Please enter a note</MemoPlaceholder>
</root>

View File

@@ -11,6 +11,20 @@
<Friday>周五</Friday>
<Saturday>周六</Saturday>
<NoRecords>还未产生账单</NoRecords>
<Memo>点此记录</Memo>
<TapToMemo>点此记录</TapToMemo>
<TitleDateFormat>yyyy年MM月dd日</TitleDateFormat>
<Balance>余额</Balance>
<Assets>资产</Assets>
<Liability>负债</Liability>
<AddAccount>新建账户</AddAccount>
<AccountName>账户名称</AccountName>
<AccountNamePlaceholder>请输入账户名称</AccountNamePlaceholder>
<Icon>图标</Icon>
<Category>种类</Category>
<Balance>余额</Balance>
<BalancePlaceholder>请输入余额</BalancePlaceholder>
<Currency>币种</Currency>
<CNY>人民币 (CNY)</CNY>
<Memo>备注</Memo>
<MemoPlaceholder>请输入备注</MemoPlaceholder>
</root>

View File

@@ -0,0 +1,41 @@
using System.Xml.Linq;
namespace Billing.Models;
public class Account : BaseModel
{
public int Id { get; set; }
public string Icon { get; set; } = ICON_DEFAULT;
public AccountCategory Category { get; set; }
public string Name { get; set; }
public decimal Balance { get; set; }
public string Memo { get; set; }
public override void OnXmlDeserialize(XElement node)
{
Id = Read(node, nameof(Id), 0);
Icon = Read(node, nameof(Icon), ICON_DEFAULT);
Category = (AccountCategory)Read(node, nameof(Category), 0);
Name = Read(node, nameof(Name), string.Empty);
Balance = Read(node, nameof(Balance), 0m);
Memo = Read(node, nameof(Memo), null);
}
public override void OnXmlSerialize(XElement node)
{
Write(node, nameof(Id), Id);
Write(node, nameof(Icon), Icon);
Write(node, nameof(Category), (int)Category);
Write(node, nameof(Name), Name);
Write(node, nameof(Balance), Balance);
Write(node, nameof(Memo), Memo);
}
}
public enum AccountCategory
{
Cash = 0,
CreditCard,
DebitCard,
ElecAccount
}

View File

@@ -16,6 +16,8 @@ public interface IModel
public abstract class BaseModel : IModel, IDisposable
{
protected const string ICON_DEFAULT = "ic_default";
private bool disposed = false;
public static T ParseXml<T>(string xml) where T : BaseModel, new()

View File

@@ -8,6 +8,7 @@ public class Billing : BaseModel
public decimal Amount { get; set; }
public string Name { get; set; }
public int CategoryId { get; set; }
public int WalletId { get; set; }
public string Store { get; set; }
public DateTime CreateTime { get; set; }
@@ -16,6 +17,7 @@ public class Billing : BaseModel
Amount = Read(node, nameof(Amount), 0m);
Name = Read(node, nameof(Name), string.Empty);
CategoryId = Read(node, nameof(CategoryId), -1);
WalletId = Read(node, nameof(WalletId), -1);
Store = Read(node, nameof(Store), string.Empty);
CreateTime = Read(node, nameof(CreateTime), default(DateTime));
}
@@ -25,6 +27,7 @@ public class Billing : BaseModel
Write(node, nameof(Amount), Amount);
Write(node, nameof(Name), Name);
Write(node, nameof(CategoryId), CategoryId);
Write(node, nameof(WalletId), WalletId);
Write(node, nameof(Store), Store);
Write(node, nameof(CreateTime), CreateTime);
}

View File

@@ -5,12 +5,14 @@ namespace Billing.Models;
public class Category : BaseModel
{
public int Id { get; set; }
public string Icon { get; set; } = ICON_DEFAULT;
public string Name { get; set; }
public int? ParentId { get; set; }
public override void OnXmlDeserialize(XElement node)
{
Id = Read(node, nameof(Id), 0);
Icon = Read(node, nameof(Icon), ICON_DEFAULT);
Name = Read(node, nameof(Name), string.Empty);
var parentId = Read(node, nameof(ParentId), -1);
if (parentId >= 0)
@@ -22,6 +24,7 @@ public class Category : BaseModel
public override void OnXmlSerialize(XElement node)
{
Write(node, nameof(Id), Id);
Write(node, nameof(Icon), Icon);
Write(node, nameof(Name), Name);
if (ParentId != null)
{

View File

@@ -9,7 +9,9 @@ public abstract class BaseTheme : ResourceDictionary
public const string CascadiaFontBold = nameof(CascadiaFontBold);
public const string RobotoCondensedFontRegular = nameof(RobotoCondensedFontRegular);
public const string RobotoCondensedFontBold = nameof(RobotoCondensedFontBold);
public const string WindowBackgroundColor = nameof(WindowBackgroundColor);
public const string OptionTintColor = nameof(OptionTintColor);
public const string PromptBackgroundColor = nameof(PromptBackgroundColor);
public const string PrimaryColor = nameof(PrimaryColor);
public const string SecondaryColor = nameof(SecondaryColor);
@@ -18,7 +20,8 @@ public abstract class BaseTheme : ResourceDictionary
public const string TabBarUnselectedColor = nameof(TabBarUnselectedColor);
public const string OutRangeDayColor = nameof(OutRangeDayColor);
public const string TextColor = nameof(TextColor);
public const string WeekendColor = nameof(WeekendColor);
public const string SecondaryTextColor = nameof(SecondaryTextColor);
public const string RedColor = nameof(RedColor);
protected abstract Color PrimaryMauiColor { get; }
protected abstract Color SecondaryMauiColor { get; }
@@ -44,6 +47,14 @@ public abstract class BaseTheme : ResourceDictionary
new Setter { Property = Label.FontFamilyProperty, Value = robotoRegularFontFamily }
}
});
Add(new Style(typeof(OptionEntry))
{
Setters =
{
new Setter { Property = Entry.FontSizeProperty, Value = Device.GetNamedSize(NamedSize.Small, typeof(Entry)) },
new Setter { Property = Entry.FontFamilyProperty, Value = robotoRegularFontFamily }
}
});
Add(new Style(typeof(Button))
{
Setters =

View File

@@ -1,4 +1,5 @@
using Xamarin.Forms;
using Billing.UI;
using Xamarin.Forms;
namespace Billing.Themes;
@@ -20,12 +21,14 @@ public class Dark : BaseTheme
private void InitColors()
{
Add(WindowBackgroundColor, Color.Black);
Add(OptionTintColor, Color.FromRgb(28, 28, 28));
Add(PromptBackgroundColor, Color.FromRgb(0x1f, 0x1f, 0x1f));
Add(TabBarBackgroundColor, Color.Black);
Add(TabBarUnselectedColor, Color.FromRgb(0x82, 0x82, 0x82));
Add(OutRangeDayColor, Color.DarkGray);
Add(TextColor, Color.FromRgb(0xcc, 0xcc, 0xcc));
Add(WeekendColor, Color.FromRgb(211, 5, 5));
Add(SecondaryTextColor, Color.LightGray);
Add(RedColor, Color.FromRgb(211, 5, 5));
Add(new Style(typeof(TabBar))
{
@@ -36,5 +39,12 @@ public class Dark : BaseTheme
new Setter { Property = Shell.TabBarUnselectedColorProperty, Value = Color.FromRgb(0x82, 0x82, 0x82) }
}
});
Add(new Style(typeof(TableView))
{
Setters =
{
new Setter { Property = VisualElement.BackgroundColorProperty, Value = Color.Black }
}
});
}
}

View File

@@ -1,4 +1,5 @@
using Xamarin.Forms;
using Billing.UI;
using Xamarin.Forms;
namespace Billing.Themes;
@@ -20,12 +21,14 @@ public class Light : BaseTheme
private void InitColors()
{
Add(WindowBackgroundColor, Color.White);
Add(OptionTintColor, Color.White);
Add(PromptBackgroundColor, Color.FromRgb(0xe0, 0xe0, 0xe0));
Add(TabBarBackgroundColor, Color.White);
Add(TabBarUnselectedColor, Color.FromRgb(0x82, 0x82, 0x82));
Add(OutRangeDayColor, Color.LightGray);
Add(TextColor, Color.FromRgb(0x33, 0x33, 0x33));
Add(WeekendColor, Color.FromRgb(211, 64, 85));
Add(SecondaryTextColor, Color.DimGray);
Add(RedColor, Color.FromRgb(211, 64, 85));
Add(new Style(typeof(TabBar))
{
@@ -36,5 +39,12 @@ public class Light : BaseTheme
new Setter { Property = Shell.TabBarUnselectedColorProperty, Value = Color.FromRgb(0x82, 0x82, 0x82) }
}
});
Add(new Style(typeof(TableView))
{
Setters =
{
new Setter { Property = VisualElement.BackgroundColorProperty, Value = Color.FromRgb(242, 241, 245) }
}
});
}
}

View File

@@ -37,7 +37,7 @@
<TapGestureRecognizer Command="{Binding OnDayTapped, Source={x:Reference billingDate}}" CommandParameter="{TemplateBinding BillingDay}"/>
</Grid.GestureRecognizers>
<Label Style="{StaticResource dateLabel}" Text="{TemplateBinding BillingDay.Text}"
TextColor="{DynamicResource WeekendColor}"
TextColor="{DynamicResource RedColor}"
FontFamily="{TemplateBinding BillingDay.FontFamily}"
Opacity="{TemplateBinding BillingDay.TextOpacity}"/>
<StackLayout Grid.Row="1"

View File

@@ -1,4 +1,3 @@
using Billing.Themes;
using System;
using Xamarin.Forms;

View File

@@ -21,3 +21,20 @@ public class TitleDateConverter : IValueConverter
return value;
}
}
public class MoneyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is decimal d)
{
return "¥ " + d.ToString("n2", CultureInfo.InvariantCulture);
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}

View File

@@ -1,4 +1,5 @@
using System;
using Billing.Themes;
using System;
using Xamarin.Forms;
namespace Billing.UI;
@@ -29,3 +30,125 @@ public class LongPressButton : Button
LongPressed?.Invoke(this, EventArgs.Empty);
}
}
public class OptionEntry : Entry { }
public abstract class OptionCell : ViewCell
{
public static readonly BindableProperty TitleProperty = BindableProperty.Create(nameof(Title), typeof(string), typeof(OptionCell));
public static readonly BindableProperty BackgroundColorProperty = BindableProperty.Create(nameof(BackgroundColor), typeof(Color), typeof(OptionCell));
public string Title
{
get => (string)GetValue(TitleProperty);
set => SetValue(TitleProperty, value);
}
public Color BackgroundColor
{
get => (Color)GetValue(BackgroundColorProperty);
set => SetValue(BackgroundColorProperty, value);
}
protected abstract View Content { get; }
public OptionCell()
{
View = new Grid
{
BindingContext = this,
Padding = new Thickness(20, 0),
ColumnDefinitions =
{
new ColumnDefinition { Width = new GridLength(.3, GridUnitType.Star) },
new ColumnDefinition { Width = new GridLength(.7, GridUnitType.Star) }
},
Children =
{
new Label
{
LineBreakMode = LineBreakMode.TailTruncation,
VerticalOptions = LayoutOptions.Center
}
.Binding(Label.TextProperty, nameof(Title))
.DynamicResource(Label.TextColorProperty, BaseTheme.TextColor),
Content.GridColumn(1)
}
}
.DynamicResource(VisualElement.BackgroundColorProperty, BaseTheme.OptionTintColor);
}
}
public class OptionTextCell : OptionCell
{
public static readonly BindableProperty DetailProperty = BindableProperty.Create(nameof(Detail), typeof(string), typeof(OptionTextCell));
public string Detail
{
get => (string)GetValue(DetailProperty);
set => SetValue(DetailProperty, value);
}
protected override View Content => new Label
{
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.Center
}
.Binding(Label.TextProperty, nameof(Detail))
.DynamicResource(Label.TextColorProperty, BaseTheme.SecondaryTextColor);
}
public class OptionSwitchCell : OptionCell
{
public static readonly BindableProperty IsToggledProperty = BindableProperty.Create(nameof(IsToggled), typeof(bool), typeof(OptionSwitchCell));
public bool IsToggled
{
get => (bool)GetValue(IsToggledProperty);
set => SetValue(IsToggledProperty, value);
}
protected override View Content => new Switch
{
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.Center
}
.Binding(Switch.IsToggledProperty, nameof(IsToggled), BindingMode.TwoWay);
}
public class OptionEntryCell : OptionCell
{
public static readonly BindableProperty TextProperty = BindableProperty.Create(nameof(Text), typeof(string), typeof(OptionEntryCell));
public static readonly BindableProperty KeyboardProperty = BindableProperty.Create(nameof(Keyboard), typeof(Keyboard), typeof(OptionEntryCell));
public static readonly BindableProperty PlaceholderProperty = BindableProperty.Create(nameof(Placeholder), typeof(string), typeof(OptionEntryCell));
public string Text
{
get => (string)GetValue(TextProperty);
set => SetValue(TextProperty, value);
}
public Keyboard Keyboard
{
get => (Keyboard)GetValue(KeyboardProperty);
set => SetValue(KeyboardProperty, value);
}
public string Placeholder
{
get => (string)GetValue(PlaceholderProperty);
set => SetValue(PlaceholderProperty, value);
}
protected override View Content => new OptionEntry
{
HorizontalOptions = LayoutOptions.Fill,
HorizontalTextAlignment = TextAlignment.End,
VerticalOptions = LayoutOptions.Center,
ReturnType = ReturnType.Next
}
.Binding(Entry.TextProperty, nameof(Text), BindingMode.TwoWay)
.Binding(InputView.KeyboardProperty, nameof(Keyboard))
.Binding(Entry.PlaceholderProperty, nameof(Placeholder))
.DynamicResource(Entry.TextColorProperty, BaseTheme.TextColor)
.DynamicResource(Entry.PlaceholderColorProperty, BaseTheme.SecondaryTextColor)
.DynamicResource(VisualElement.BackgroundColorProperty, BaseTheme.OptionTintColor);
}

View File

@@ -0,0 +1,15 @@
using Xamarin.Forms;
namespace Billing.UI;
public class ShadowEffect : RoutingEffect
{
public float Radius { get; set; }
public Color Color { get; set; }
public Size Offect { get; set; }
public float Opacity { get; set; }
public ShadowEffect() : base($"Org.Tsanie.{nameof(ShadowEffect)}")
{
}
}

View File

@@ -1,4 +1,7 @@
namespace Billing.UI;
using System;
using Xamarin.Forms;
namespace Billing.UI;
public static partial class Definition
{
@@ -7,3 +10,59 @@ public static partial class Definition
public static partial string GetRobotoCondensedRegularFontFamily();
public static partial string GetRobotoCondensedBoldFontFamily();
}
public static class ExtensionHelper
{
public static View Binding(this View view, BindableProperty property, string path, BindingMode mode = BindingMode.Default, IValueConverter converter = null)
{
view.SetBinding(property, path, mode, converter);
return view;
}
public static View DynamicResource(this View view, BindableProperty property, string key)
{
view.SetDynamicResource(property, key);
return view;
}
public static View GridColumn(this View view, int column)
{
Grid.SetColumn(view, column);
return view;
}
public static View GridRow(this View view, int row)
{
Grid.SetRow(view, row);
return view;
}
}
public class Tap : IDisposable
{
private readonly static object sync = new();
private static Tap instance;
private bool busy = false;
private Tap() { }
public static bool IsBusy => instance?.busy ?? false;
public static Tap Start()
{
lock (sync)
{
(instance ??= new Tap()).busy = true;
}
return instance;
}
public void Dispose()
{
lock (sync)
{
busy = false;
}
}
}

View File

@@ -2,12 +2,44 @@
<ui:BillingPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:r="clr-namespace:Billing.Languages"
xmlns:ui="clr-namespace:Billing.UI"
xmlns:v="clr-namespace:Billing.Views"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Billing.Views.AccountPage"
Title="{r:Text Accounts}">
<StackLayout>
<Label Text="Welcome to Account Page!"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
</StackLayout>
x:Name="accountPage"
x:DataType="v:AccountPage"
Title="{r:Text Accounts}"
BindingContext="{x:Reference accountPage}">
<ContentPage.Resources>
<ui:MoneyConverter x:Key="moneyConverter"/>
</ContentPage.Resources>
<ContentPage.ToolbarItems>
<ToolbarItem Order="Primary" IconImageSource="plus.png" Command="{Binding AddAccount}"/>
</ContentPage.ToolbarItems>
<ScrollView>
<StackLayout>
<Grid HeightRequest="100" BackgroundColor="{DynamicResource PromptBackgroundColor}" ColumnDefinitions="Auto, *">
<!--<Grid.Effects>
<ui:ShadowEffect Offect="0, 3" Color="Black" Opacity=".4"/>
</Grid.Effects>-->
<StackLayout VerticalOptions="Center" Margin="20, 0" Spacing="0">
<Label FontSize="Small" Text="{r:Text Balance}"/>
<Label FontSize="24" FontFamily="{DynamicResource RobotoCondensedFontBold}"
Text="{Binding Balance, Converter={StaticResource moneyConverter}}"/>
</StackLayout>
<Grid Grid.Column="1" Margin="20, 0" VerticalOptions="Center" HorizontalOptions="End"
ColumnDefinitions="Auto, Auto" RowDefinitions="Auto, Auto">
<Label FontSize="Small" HorizontalOptions="End" Text="{r:Text Assets}"/>
<Label Grid.Column="1" FontSize="Small" Margin="10, 0, 0, 0" HorizontalOptions="End"
Text="{Binding Asset, Converter={StaticResource moneyConverter}}"/>
<Label Grid.Row="1" FontSize="Small" HorizontalOptions="End" Text="{r:Text Liability}"/>
<Label Grid.Row="1" Grid.Column="1" FontSize="Small" Margin="10, 0, 0, 0" HorizontalOptions="End"
TextColor="{DynamicResource RedColor}"
Text="{Binding Liability, Converter={StaticResource moneyConverter}}"/>
</Grid>
</Grid>
</StackLayout>
</ScrollView>
</ui:BillingPage>

View File

@@ -1,11 +1,44 @@
using Billing.UI;
using System;
using Xamarin.Forms;
namespace Billing.Views;
public partial class AccountPage : BillingPage
{
private static readonly BindableProperty BalanceProperty = BindableProperty.Create(nameof(Balance), typeof(decimal), typeof(AccountPage));
private static readonly BindableProperty AssetProperty = BindableProperty.Create(nameof(Asset), typeof(decimal), typeof(AccountPage));
private static readonly BindableProperty LiabilityProperty = BindableProperty.Create(nameof(Liability), typeof(decimal), typeof(AccountPage));
public decimal Balance => (decimal)GetValue(BalanceProperty);
public decimal Asset => (decimal)GetValue(AssetProperty);
public decimal Liability => (decimal)GetValue(LiabilityProperty);
public Command AddAccount { get; }
public AccountPage()
{
AddAccount = new Command(OnAddAccount);
InitializeComponent();
}
private async void OnAddAccount()
{
if (Tap.IsBusy)
{
return;
}
using (Tap.Start())
{
var page = new AddAccountPage();
page.AccountChecked += AccountChecked;
await Navigation.PushAsync(page);
}
}
private void AccountChecked(object sender, AccountEventArgs e)
{
Helper.Debug(e.Account.ToString());
}
}

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8" ?>
<ui:BillingPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:r="clr-namespace:Billing.Languages"
xmlns:ui="clr-namespace:Billing.UI"
xmlns:v="clr-namespace:Billing.Views"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Billing.Views.AddAccountPage"
x:Name="addAccountPage"
x:DataType="v:AddAccountPage"
Title="{r:Text AddAccount}"
BindingContext="{x:Reference addAccountPage}">
<ContentPage.ToolbarItems>
<ToolbarItem Order="Primary" IconImageSource="check.png" Command="{Binding CheckAccount}"/>
</ContentPage.ToolbarItems>
<ContentPage.Content>
<TableView Intent="Settings">
<TableSection>
<ui:OptionEntryCell Title="{r:Text AccountName}"
Text="{Binding AccountName, Mode=TwoWay}"
Keyboard="Text" Placeholder="{r:Text AccountNamePlaceholder}"/>
<ui:OptionTextCell Title="{r:Text Icon}"
Detail="{Binding AccountIcon}"/>
</TableSection>
<TableSection>
<ui:OptionEntryCell Title="{r:Text Balance}"
Text="{Binding Balance, Mode=TwoWay}"
Keyboard="Numeric" Placeholder="{r:Text BalancePlaceholder}"/>
<ui:OptionTextCell Title="{r:Text Currency}"
Detail="{r:Text CNY}"/>
</TableSection>
<TableSection>
<ui:OptionEntryCell Title="{r:Text Memo}"
Text="{Binding Memo, Mode=TwoWay}"
Keyboard="Plain" Placeholder="{r:Text MemoPlaceholder}"/>
</TableSection>
</TableView>
</ContentPage.Content>
</ui:BillingPage>

View File

@@ -0,0 +1,86 @@
using Billing.Models;
using Billing.UI;
using System;
using Xamarin.Forms;
namespace Billing.Views;
public partial class AddAccountPage : BillingPage
{
private static readonly BindableProperty AccountNameProperty = BindableProperty.Create(nameof(AccountName), typeof(string), typeof(AddAccountPage));
private static readonly BindableProperty AccountIconProperty = BindableProperty.Create(nameof(AccountIcon), typeof(string), typeof(AddAccountPage));
private static readonly BindableProperty CategoryProperty = BindableProperty.Create(nameof(Category), typeof(string), typeof(AddAccountPage));
private static readonly BindableProperty BalanceProperty = BindableProperty.Create(nameof(Balance), typeof(decimal), typeof(AddAccountPage));
private static readonly BindableProperty MemoProperty = BindableProperty.Create(nameof(Memo), typeof(string), typeof(AddAccountPage));
public string AccountName
{
get => (string)GetValue(AccountNameProperty);
set => SetValue(AccountNameProperty, value);
}
public string AccountIcon
{
get => (string)GetValue(AccountIconProperty);
set => SetValue(AccountIconProperty, value);
}
public string Category
{
get => (string)GetValue(CategoryProperty);
set => SetValue(CategoryProperty, value);
}
public decimal Balance
{
get => (decimal)GetValue(BalanceProperty);
set => SetValue(BalanceProperty, value);
}
public string Memo
{
get => (string)GetValue(MemoProperty);
set => SetValue(MemoProperty, value);
}
private readonly Account account;
public Command CheckAccount { get; }
public event EventHandler<AccountEventArgs> AccountChecked;
public AddAccountPage()
{
CheckAccount = new Command(OnCheckAccount);
InitializeComponent();
}
public AddAccountPage(Account account)
{
this.account = account;
AccountName = account.Name;
AccountIcon = account.Icon;
Category = account.Category.ToString();
Balance = account.Balance;
Memo = account.Memo;
CheckAccount = new Command(OnCheckAccount);
InitializeComponent();
}
private void OnCheckAccount()
{
AccountChecked?.Invoke(this, new AccountEventArgs
{
Account = new Account
{
Id = account?.Id ?? -1,
Name = AccountName,
Icon = AccountIcon,
//Category = Category,
Balance = Balance,
Memo = Memo
}
});
}
}
public class AccountEventArgs : EventArgs
{
public Account Account { get; set; }
}

View File

@@ -39,7 +39,7 @@
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding AddBilling}"/>
</StackLayout.GestureRecognizers>
<Label Text="{r:Text Memo}" TextColor="{DynamicResource PrimaryColor}"
<Label Text="{r:Text TapToMemo}" TextColor="{DynamicResource PrimaryColor}"
VerticalOptions="Center"/>
<!--<Label Style="{DynamicResource IconLightStyle}"
Text="{x:Static local:Definition.IconRight}"