fixes edition cache
This commit is contained in:
parent
8abec56e8a
commit
5dea4ee707
24 changed files with 269 additions and 102 deletions
|
|
@ -107,7 +107,7 @@ namespace BookAStar.Droid
|
||||||
|
|
||||||
LoadApplication(fapp);
|
LoadApplication(fapp);
|
||||||
|
|
||||||
CheckSharing();
|
var componentName = StartService(new Intent(this, typeof(YavscChooserTargetService)));
|
||||||
|
|
||||||
// TabLayoutResource = Resource.Layout.Tabbar;
|
// TabLayoutResource = Resource.Layout.Tabbar;
|
||||||
// ToolbarResource = Resource.Layout.Toolbar;
|
// ToolbarResource = Resource.Layout.Toolbar;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="fr.pschneider.bas" android:installLocation="auto">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="fr.pschneider.bas" android:installLocation="auto">
|
||||||
<uses-sdk android:minSdkVersion="15" />
|
<uses-sdk android:minSdkVersion="15" />
|
||||||
<application android:label="BookAStar" android:icon="@drawable/icon" android:theme="@style/MainTheme">
|
<application android:allowBackup="true" android:label="Booking Star" android:icon="@drawable/icon" android:theme="@style/MainTheme">
|
||||||
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzaSyBLSEDhZixwpHDsWmO2pKwgGDJReoTuQ7A" />
|
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzaSyBLSEDhZixwpHDsWmO2pKwgGDJReoTuQ7A" />
|
||||||
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
|
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
|
||||||
<receiver android:name="com.google.android.gms.gcm.GcmReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
|
<receiver android:name="com.google.android.gms.gcm.GcmReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
|
||||||
|
|
@ -17,21 +17,19 @@
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<service android:name="fr.pschneider.bas.YavscChooserTargetService"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.service.chooser.ChooserTargetService" />
|
|
||||||
</intent-filter>
|
|
||||||
</service>
|
|
||||||
<activity android:name="fr.pschneider.bas.SendFilesActivity" android:label="@string/app_name">
|
<activity android:name="fr.pschneider.bas.SendFilesActivity" android:label="@string/app_name">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.SEND" />
|
<action android:name="android.intent.action.SEND" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<data android:mimeType="text/plain" />
|
<!-- <data android:mimeType="text/plain" /> -->
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
<meta-data android:name="android.service.chooser.chooser_target_service" android:value="fr.pschneider.bas.YavscChooserTargetService" />
|
<meta-data android:name="android.service.chooser.chooser_target_service" android:value="fr.pschneider.bas.YavscChooserTargetService" />
|
||||||
</activity>
|
</activity>
|
||||||
|
<service android:name="fr.pschneider.bas.YavscChooserTargetService" android:label="@string/app_name" android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.service.chooser.ChooserTargetService" />
|
||||||
|
</intent-filter>
|
||||||
|
</service>
|
||||||
</application>
|
</application>
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.WAVE_LOCK" />
|
<uses-permission android:name="android.permission.WAVE_LOCK" />
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,19 @@ using Android.Runtime;
|
||||||
using Android.Views;
|
using Android.Views;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using Android.Service.Chooser;
|
using Android.Service.Chooser;
|
||||||
|
using static Android.Manifest;
|
||||||
|
|
||||||
namespace BookAStar.Droid
|
namespace BookAStar.Droid
|
||||||
{
|
{
|
||||||
[Service(Name = "fr.pschneider.bas.YavscChooserTargetService", Label = "Yavsc share service", Permission = "android.permission.BIND_CHOOSER_TARGET_SERVICE", Icon = "@drawable/icon", Exported = true)]
|
[Service(
|
||||||
|
Name = "fr.pschneider.bas.YavscChooserTargetService",
|
||||||
|
Label = "Yavsc share service",
|
||||||
|
Permission = Permission.BindChooserTargetService,
|
||||||
|
Icon = "@drawable/icon",
|
||||||
|
Exported = true,
|
||||||
|
Enabled = true
|
||||||
|
)]
|
||||||
|
[IntentFilter(new String[] { "android.service.chooser.ChooserTargetService" })]
|
||||||
class YavscChooserTargetService : ChooserTargetService
|
class YavscChooserTargetService : ChooserTargetService
|
||||||
{
|
{
|
||||||
public override IList<ChooserTarget> OnGetChooserTargets(ComponentName targetActivityName, IntentFilter matchedFilter)
|
public override IList<ChooserTarget> OnGetChooserTargets(ComponentName targetActivityName, IntentFilter matchedFilter)
|
||||||
|
|
@ -24,7 +33,7 @@ namespace BookAStar.Droid
|
||||||
ChooserTarget t = new ChooserTarget(
|
ChooserTarget t = new ChooserTarget(
|
||||||
new Java.Lang.String(
|
new Java.Lang.String(
|
||||||
"BookingStar"), i,
|
"BookingStar"), i,
|
||||||
.5f, new ComponentName(this.BaseContext, ".SendFilesActivity"),
|
.5f, new ComponentName(this, "BookAStar.SendFilesActivity"),
|
||||||
null);
|
null);
|
||||||
var res = new List<ChooserTarget>();
|
var res = new List<ChooserTarget>();
|
||||||
res.Add(t);
|
res.Add(t);
|
||||||
|
|
@ -35,10 +44,5 @@ namespace BookAStar.Droid
|
||||||
{
|
{
|
||||||
return base.OnBind(intent);
|
return base.OnBind(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnCreate()
|
|
||||||
{
|
|
||||||
base.OnCreate();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
<OnPlatform x:TypeArguments="Font" Android="Large" iOS="Large" WinPhone="Large" x:Key="HeaderFont" />
|
<OnPlatform x:TypeArguments="Font" Android="Large" iOS="Large" WinPhone="Large" x:Key="HeaderFont" />
|
||||||
<OnPlatform x:TypeArguments="Color" Android="Red" iOS="Red" WinPhone="Red" x:Key="EmphasisTextColor" />
|
<OnPlatform x:TypeArguments="Color" Android="Red" iOS="Red" WinPhone="Red" x:Key="EmphasisTextColor" />
|
||||||
<OnPlatform x:TypeArguments="Font" Android="60" iOS="60" WinPhone="60" x:Key="LargeFontSize" />
|
<OnPlatform x:TypeArguments="Font" Android="90" iOS="90" WinPhone="90" x:Key="LargeFontSize" />
|
||||||
<OnPlatform x:TypeArguments="Font" Android="50" iOS="50" WinPhone="50" x:Key="MediumFontSize" />
|
<OnPlatform x:TypeArguments="Font" Android="50" iOS="50" WinPhone="50" x:Key="MediumFontSize" />
|
||||||
<OnPlatform x:TypeArguments="Font" Android="40" iOS="40" WinPhone="40" x:Key="SmallFontSize" />
|
<OnPlatform x:TypeArguments="Font" Android="40" iOS="40" WinPhone="40" x:Key="SmallFontSize" />
|
||||||
<OnPlatform x:TypeArguments="x:Double" Android="130" iOS="130" WinPhone="130" x:Key="BigUserAvatarSize" />
|
<OnPlatform x:TypeArguments="x:Double" Android="130" iOS="130" WinPhone="130" x:Key="BigUserAvatarSize" />
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ namespace BookAStar
|
||||||
{
|
{
|
||||||
// TODO save the navigation stack
|
// TODO save the navigation stack
|
||||||
int position = 0;
|
int position = 0;
|
||||||
|
|
||||||
foreach (Page page in MainPage.Navigation.NavigationStack)
|
foreach (Page page in MainPage.Navigation.NavigationStack)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,9 @@
|
||||||
<Compile Include="Behaviors\PickerBehavior.cs" />
|
<Compile Include="Behaviors\PickerBehavior.cs" />
|
||||||
<Compile Include="Behaviors\StarBehavior.cs" />
|
<Compile Include="Behaviors\StarBehavior.cs" />
|
||||||
<Compile Include="Constants.cs" />
|
<Compile Include="Constants.cs" />
|
||||||
|
<Compile Include="Data\LocalState.cs" />
|
||||||
<Compile Include="Model\UI\PageState.cs" />
|
<Compile Include="Model\UI\PageState.cs" />
|
||||||
|
<Compile Include="ViewModels\EditingViewModel.cs" />
|
||||||
<Compile Include="Views\EnumPicker.cs" />
|
<Compile Include="Views\EnumPicker.cs" />
|
||||||
<Compile Include="Converters\BooleanToObjectConverter.cs" />
|
<Compile Include="Converters\BooleanToObjectConverter.cs" />
|
||||||
<Compile Include="Converters\EnumConverter.cs" />
|
<Compile Include="Converters\EnumConverter.cs" />
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
using System.Threading.Tasks;
|
namespace BookAStar.Data
|
||||||
|
|
||||||
namespace BookAStar.Data
|
|
||||||
{
|
{
|
||||||
using Model;
|
using Model;
|
||||||
using Model.Blog;
|
using Model.Blog;
|
||||||
using Model.Workflow;
|
using Model.Workflow;
|
||||||
using Model.UI;
|
using Model.UI;
|
||||||
|
using ViewModels;
|
||||||
|
|
||||||
public class DataManager
|
public class DataManager
|
||||||
{
|
{
|
||||||
|
|
@ -15,11 +14,20 @@ namespace BookAStar.Data
|
||||||
public RemoteEntity<Blog, long> Blogspot { get; set; }
|
public RemoteEntity<Blog, long> Blogspot { get; set; }
|
||||||
public LocalEntity<ClientProviderInfo,string> Contacts { get; set; }
|
public LocalEntity<ClientProviderInfo,string> Contacts { get; set; }
|
||||||
internal LocalEntity<PageState, int> AppState { get; set; }
|
internal LocalEntity<PageState, int> AppState { get; set; }
|
||||||
protected static DataManager current = new DataManager();
|
/// <summary>
|
||||||
|
/// They have no remote exisence ...
|
||||||
|
/// </summary>
|
||||||
|
internal LocalEntity<EditEstimateViewModel, long> EstimationCache { get; set; }
|
||||||
|
internal LocalEntity<BillingLine, string> EstimateLinesTemplates { get; set; }
|
||||||
|
|
||||||
|
protected static DataManager current ;
|
||||||
|
|
||||||
public static DataManager Current
|
public static DataManager Current
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
if (current == null)
|
||||||
|
current = new DataManager();
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -34,17 +42,17 @@ namespace BookAStar.Data
|
||||||
x=>x.Id);
|
x=>x.Id);
|
||||||
Contacts = new LocalEntity<ClientProviderInfo, string>(c => c.UserId);
|
Contacts = new LocalEntity<ClientProviderInfo, string>(c => c.UserId);
|
||||||
AppState = new LocalEntity<PageState, int>(s => s.Position);
|
AppState = new LocalEntity<PageState, int>(s => s.Position);
|
||||||
|
EstimationCache = new LocalEntity<EditEstimateViewModel, long>(
|
||||||
|
e => e.Query.Id);
|
||||||
|
EstimateLinesTemplates = new LocalEntity<BillingLine, string>(
|
||||||
|
l => l.Description);
|
||||||
BookQueries.Load();
|
BookQueries.Load();
|
||||||
Estimates.Load();
|
Estimates.Load();
|
||||||
Blogspot.Load();
|
Blogspot.Load();
|
||||||
Contacts.Load();
|
Contacts.Load();
|
||||||
AppState.Load();
|
AppState.Load();
|
||||||
}
|
EstimationCache.Load();
|
||||||
|
EstimateLinesTemplates.Load();
|
||||||
public async Task<BookQueryData> GetBookQuery(long bookQueryId)
|
|
||||||
{
|
|
||||||
return await BookQueries.Get(bookQueryId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ namespace BookAStar.Data
|
||||||
|
|
||||||
public V LocalGet(K key)
|
public V LocalGet(K key)
|
||||||
{
|
{
|
||||||
|
if (!this.Any(x => GetKey(x).Equals(key)))
|
||||||
|
return default(V);
|
||||||
CurrentItem = this.Single(x => GetKey(x).Equals(key));
|
CurrentItem = this.Single(x => GetKey(x).Equals(key));
|
||||||
return CurrentItem;
|
return CurrentItem;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
16
BookAStar/BookAStar/Data/LocalState.cs
Normal file
16
BookAStar/BookAStar/Data/LocalState.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BookAStar.Data
|
||||||
|
{
|
||||||
|
public enum LocalState
|
||||||
|
{
|
||||||
|
UpToDate = 0,
|
||||||
|
New,
|
||||||
|
Edited,
|
||||||
|
Removed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,7 +10,7 @@ namespace BookAStar.Data
|
||||||
{
|
{
|
||||||
using Helpers;
|
using Helpers;
|
||||||
|
|
||||||
public class RemoteEntity<V,K> : LocalEntity<V, K>, ICommand where K : IEquatable<K>
|
public class RemoteEntity<V, K> : LocalEntity<V, K>, ICommand where K : IEquatable<K>
|
||||||
{
|
{
|
||||||
private string _controller;
|
private string _controller;
|
||||||
public event EventHandler CanExecuteChanged;
|
public event EventHandler CanExecuteChanged;
|
||||||
|
|
@ -22,7 +22,7 @@ namespace BookAStar.Data
|
||||||
return !IsExecuting && (MainSettings.CurrentUser != null);
|
return !IsExecuting && (MainSettings.CurrentUser != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RemoteEntity(string controllerName, Func<V,K> getKey):base(getKey)
|
public RemoteEntity(string controllerName, Func<V, K> getKey) : base(getKey)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(controllerName))
|
if (string.IsNullOrWhiteSpace(controllerName))
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
|
|
@ -35,7 +35,8 @@ namespace BookAStar.Data
|
||||||
if (IsExecuting)
|
if (IsExecuting)
|
||||||
throw new InvalidOperationException("Already executing");
|
throw new InvalidOperationException("Already executing");
|
||||||
IsExecuting = true;
|
IsExecuting = true;
|
||||||
CanExecuteChanged.Invoke(this, new EventArgs());
|
if (CanExecuteChanged != null)
|
||||||
|
CanExecuteChanged.Invoke(this, new EventArgs());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -65,7 +66,8 @@ namespace BookAStar.Data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (WebException webex) {
|
catch (WebException webex)
|
||||||
|
{
|
||||||
throw new ServiceNotAvailable("No remote entity", webex);
|
throw new ServiceNotAvailable("No remote entity", webex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,25 +78,26 @@ namespace BookAStar.Data
|
||||||
private void AfterExecuting()
|
private void AfterExecuting()
|
||||||
{
|
{
|
||||||
IsExecuting = false;
|
IsExecuting = false;
|
||||||
CanExecuteChanged.Invoke(this, new EventArgs());
|
if (CanExecuteChanged!=null)
|
||||||
|
CanExecuteChanged.Invoke(this, new EventArgs());
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<V> Get(K key)
|
public async Task<V> Get(K key)
|
||||||
{
|
{
|
||||||
var item = LocalGet(key);
|
var item = LocalGet(key);
|
||||||
if (item==null) item = await RemoteGet(key);
|
if (item == null) item = await RemoteGet(key);
|
||||||
CurrentItem = item;
|
CurrentItem = item;
|
||||||
return CurrentItem;
|
return CurrentItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<V> RemoteGet(K key)
|
public async Task<V> RemoteGet(K key)
|
||||||
{
|
{
|
||||||
V item = default(V);
|
V item = default(V);
|
||||||
BeforeExecute();
|
BeforeExecute();
|
||||||
// Get the whole data
|
// Get the whole data
|
||||||
var uri = new Uri(controllerUri.AbsolutePath+"/"+key.ToString());
|
var uri = new Uri(controllerUri.AbsoluteUri + "/" + key.ToString());
|
||||||
|
|
||||||
using (HttpClient client = new HttpClient())
|
using (HttpClient client = UserHelpers.CreateClient())
|
||||||
{
|
{
|
||||||
using (var response = await client.GetAsync(uri))
|
using (var response = await client.GetAsync(uri))
|
||||||
{
|
{
|
||||||
|
|
@ -112,5 +115,29 @@ namespace BookAStar.Data
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async void Create(V item)
|
||||||
|
{
|
||||||
|
BeforeExecute();
|
||||||
|
|
||||||
|
using (HttpClient client = UserHelpers.CreateClient())
|
||||||
|
{
|
||||||
|
HttpContent content = new StringContent(
|
||||||
|
JsonConvert.SerializeObject(item)
|
||||||
|
);
|
||||||
|
using (var response = await client.PostAsync(controllerUri, content))
|
||||||
|
{
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
// TODO throw custom exception, and catch to inform user
|
||||||
|
throw new Exception($"Create failed posting {item} @ {controllerUri.AbsolutePath}");
|
||||||
|
var recontent = await response.Content.ReadAsStringAsync();
|
||||||
|
JsonConvert.PopulateObject(recontent, item);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AfterExecuting();
|
||||||
|
CurrentItem = item;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -156,12 +156,14 @@ namespace BookAStar
|
||||||
if (olduserid != value.Id)
|
if (olduserid != value.Id)
|
||||||
{
|
{
|
||||||
App.CurrentApp.PostDeviceInfo();
|
App.CurrentApp.PostDeviceInfo();
|
||||||
UserChanged.Invoke(App.CurrentApp, new EventArgs());
|
if (UserChanged!=null)
|
||||||
|
UserChanged.Invoke(App.CurrentApp, new EventArgs());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (olduserid != null)
|
else if (olduserid != null)
|
||||||
{
|
{
|
||||||
UserChanged.Invoke(App.CurrentApp, new EventArgs());
|
if (UserChanged != null)
|
||||||
|
UserChanged.Invoke(App.CurrentApp, new EventArgs());
|
||||||
// TODO else Unregister this device
|
// TODO else Unregister this device
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -267,7 +269,7 @@ namespace BookAStar
|
||||||
{
|
{
|
||||||
var key = $"{EntityDataSettingsPrefix}/{subKey}/{typeof(V).FullName}";
|
var key = $"{EntityDataSettingsPrefix}/{subKey}/{typeof(V).FullName}";
|
||||||
var data = AppSettings.GetValueOrDefault<string>(key, null);
|
var data = AppSettings.GetValueOrDefault<string>(key, null);
|
||||||
if (data != null)
|
if (!string.IsNullOrWhiteSpace(data))
|
||||||
{
|
{
|
||||||
var items = JsonConvert.DeserializeObject<IList<V>>(data);
|
var items = JsonConvert.DeserializeObject<IList<V>>(data);
|
||||||
if (items != null)
|
if (items != null)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
namespace BookAStar.Model.UI
|
using XLabs.Forms.Mvvm;
|
||||||
|
|
||||||
|
namespace BookAStar.Model.UI
|
||||||
{
|
{
|
||||||
internal class PageState
|
internal class PageState
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using BookAStar.Data;
|
using BookAStar.Data;
|
||||||
using BookAStar.Helpers;
|
using BookAStar.Helpers;
|
||||||
using BookAStar.Model.Interfaces;
|
using BookAStar.Model.Interfaces;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
|
|
@ -24,7 +25,7 @@ namespace BookAStar.Model.Workflow
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public IList<string> AttachedGraphics { get; set; }
|
public IList<string> AttachedGraphics { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
public string AttachedGraphicsString
|
public string AttachedGraphicsString
|
||||||
{
|
{
|
||||||
get { return AttachedGraphics==null?null:string.Join(":", AttachedGraphics); }
|
get { return AttachedGraphics==null?null:string.Join(":", AttachedGraphics); }
|
||||||
|
|
@ -38,6 +39,7 @@ namespace BookAStar.Model.Workflow
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public IList<string> AttachedFiles { get; set; }
|
public IList<string> AttachedFiles { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
public string AttachedFilesString
|
public string AttachedFilesString
|
||||||
{
|
{
|
||||||
get { return AttachedFiles == null ? null : string.Join(":", AttachedFiles); }
|
get { return AttachedFiles == null ? null : string.Join(":", AttachedFiles); }
|
||||||
|
|
@ -47,19 +49,20 @@ namespace BookAStar.Model.Workflow
|
||||||
public string OwnerId { get; set; }
|
public string OwnerId { get; set; }
|
||||||
|
|
||||||
public string ClientId { get; set; }
|
public string ClientId { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
public BookQueryData Query
|
public BookQueryData Query
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (CommandId.HasValue)
|
if (CommandId.HasValue)
|
||||||
{
|
{
|
||||||
return DataManager.Current.BookQueries.LocalGet(CommandId.Value);
|
var dm = DataManager.Current;
|
||||||
|
return dm.BookQueries.LocalGet(CommandId.Value);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
[JsonIgnore]
|
||||||
public ClientProviderInfo Client
|
public ClientProviderInfo Client
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
@ -68,7 +71,7 @@ namespace BookAStar.Model.Workflow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
public decimal Total { get
|
public decimal Total { get
|
||||||
{
|
{
|
||||||
return Bill?.Aggregate((decimal)0, (t, l) => t + l.Count * l.UnitaryCost) ?? (decimal)0;
|
return Bill?.Aggregate((decimal)0, (t, l) => t + l.Count * l.UnitaryCost) ?? (decimal)0;
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,8 @@
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" >
|
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" >
|
||||||
<maps:Map x:Name="map" VerticalOptions="FillAndExpand"></maps:Map>
|
<maps:Map x:Name="map" VerticalOptions="FillAndExpand"></maps:Map>
|
||||||
<Button Text="Faire un devis" Clicked="MakeAnEstimate" VerticalOptions="End" />
|
|
||||||
|
<Button Text="{Binding EditEstimateButtonText}" Clicked="OnEditEstimate" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</ContentPage>
|
</ContentPage>
|
||||||
|
|
@ -16,11 +16,7 @@ namespace BookAStar.Pages
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BindingContext as BookQueryData;
|
return (BindingContext as BookQueryViewModel).Data;
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
BindingContext = value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected override void OnBindingContextChanged()
|
protected override void OnBindingContextChanged()
|
||||||
|
|
@ -56,23 +52,28 @@ namespace BookAStar.Pages
|
||||||
|
|
||||||
// Task.Run( async () => { bookQuery = await App.CurrentApp.DataManager.BookQueries.Get(bookQueryId); });
|
// Task.Run( async () => { bookQuery = await App.CurrentApp.DataManager.BookQueries.Get(bookQueryId); });
|
||||||
|
|
||||||
BookQuery = bookQuery;
|
BindingContext = new BookQueryViewModel(bookQuery);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MakeAnEstimate(object sender, EventArgs ev)
|
private void OnEditEstimate(object sender, EventArgs ev)
|
||||||
{
|
{
|
||||||
DataManager.Current.Contacts.Merge(BookQuery.Client);
|
var viewModel = ((BookQueryViewModel)BindingContext).DraftEstimate;
|
||||||
var e = new Estimate()
|
if (viewModel == null)
|
||||||
{
|
{
|
||||||
ClientId = BookQuery.Client.UserId,
|
DataManager.Current.Contacts.Merge(BookQuery.Client);
|
||||||
CommandId = BookQuery.Id,
|
var e = new Estimate()
|
||||||
OwnerId = MainSettings.CurrentUser.Id,
|
{
|
||||||
Id = 0,
|
ClientId = BookQuery.Client.UserId,
|
||||||
Description = "# **Hello Estimate!**"
|
CommandId = BookQuery.Id,
|
||||||
};
|
OwnerId = MainSettings.CurrentUser.Id,
|
||||||
|
Id = 0,
|
||||||
|
Description = "# **Hello Estimate!**"
|
||||||
|
};
|
||||||
|
viewModel = new EditEstimateViewModel(e, LocalState.New);
|
||||||
|
DataManager.Current.EstimationCache.Add(viewModel);
|
||||||
|
}
|
||||||
App.NavigationService.NavigateTo<EditEstimatePage>(true,
|
App.NavigationService.NavigateTo<EditEstimatePage>(true,
|
||||||
new EditEstimateViewModel(e));
|
viewModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnSizeAllocated(double width, double height)
|
protected override void OnSizeAllocated(double width, double height)
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,14 @@
|
||||||
<ScrollView>
|
<ScrollView>
|
||||||
<StackLayout Orientation="Vertical" >
|
<StackLayout Orientation="Vertical" >
|
||||||
<StackLayout>
|
<StackLayout>
|
||||||
<StackLayout>
|
<lc:GesturesContentView ExcludeChildren="false" VisualElement.HeightRequest="{StaticResource BigUserAvatarSize}">
|
||||||
|
<StackLayout>
|
||||||
|
<Label Text="{Binding UserName}" Style="{StaticResource LabelPageHeadingStyle}"
|
||||||
|
HorizontalTextAlignment="Center"
|
||||||
|
LineBreakMode="WordWrap" XAlign="Center"
|
||||||
|
></Label>
|
||||||
|
|
||||||
<Frame VisualElement.HeightRequest="{StaticResource BigUserAvatarSize}">
|
<Frame VisualElement.HeightRequest="{StaticResource BigUserAvatarSize}">
|
||||||
<lc:GesturesContentView ExcludeChildren="false" VisualElement.HeightRequest="{StaticResource BigUserAvatarSize}">
|
|
||||||
|
|
||||||
<lb:Gestures.Interests>
|
<lb:Gestures.Interests>
|
||||||
<lb:GestureCollection>
|
<lb:GestureCollection>
|
||||||
|
|
@ -35,15 +40,13 @@
|
||||||
<Image Source="{Binding Avatar}" Aspect="AspectFit"
|
<Image Source="{Binding Avatar}" Aspect="AspectFit"
|
||||||
VisualElement.HeightRequest="{StaticResource BigUserAvatarSize}" />
|
VisualElement.HeightRequest="{StaticResource BigUserAvatarSize}" />
|
||||||
|
|
||||||
</lc:GesturesContentView>
|
|
||||||
</Frame>
|
</Frame>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
|
</lc:GesturesContentView>
|
||||||
<views:RatingView Rating="{Binding Rating, Mode=TwoWay}" x:Name="ratingView"/>
|
<views:RatingView Rating="{Binding Rating, Mode=TwoWay}" x:Name="ratingView"/>
|
||||||
|
|
||||||
<Label Text="{Binding UserName}" Style="{StaticResource LabelPageHeadingStyle}"
|
|
||||||
HorizontalTextAlignment="Center"
|
|
||||||
LineBreakMode="WordWrap" XAlign="Center"
|
|
||||||
></Label>
|
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
|
|
||||||
<Button Text="{Binding PerformerStatus}" Clicked="OnViewPerformerStatus" />
|
<Button Text="{Binding PerformerStatus}" Clicked="OnViewPerformerStatus" />
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using BookAStar.ViewModels;
|
using BookAStar.Data;
|
||||||
|
using BookAStar.ViewModels;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
@ -18,7 +19,6 @@ namespace BookAStar.Pages
|
||||||
|
|
||||||
public void OnValidateClicked (object sender, EventArgs e)
|
public void OnValidateClicked (object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
|
||||||
this.Navigation.PopAsync();
|
this.Navigation.PopAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,13 +31,12 @@
|
||||||
<Label Grid.Row="0" Grid.Column="1" Text="{Binding Query.Location.Address}" ></Label>
|
<Label Grid.Row="0" Grid.Column="1" Text="{Binding Query.Location.Address}" ></Label>
|
||||||
<Label Grid.Row="0" Grid.Column="2" Text="{Binding Query.EventDate, StringFormat='{0:dddd d MMMM yyyy à hh:mm}'}" ></Label>
|
<Label Grid.Row="0" Grid.Column="2" Text="{Binding Query.EventDate, StringFormat='{0:dddd d MMMM yyyy à hh:mm}'}" ></Label>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<Entry Placeholder="Saisissez un titre pour ce devis" Text="{Binding Title, Mode=TwoWay}" />
|
||||||
<views:MarkdownView x:Name="mdview"
|
<views:MarkdownView x:Name="mdview"
|
||||||
Editable="True"
|
Editable="True"
|
||||||
HorizontalOptions="FillAndExpand"
|
HorizontalOptions="FillAndExpand"
|
||||||
Markdown="{Binding Description, Mode=TwoWay}"
|
Markdown="{Binding Description, Mode=TwoWay}"
|
||||||
VerticalOptions="Start"
|
VerticalOptions="Start" />
|
||||||
/>
|
|
||||||
<StackLayout x:Name="biAnVaLayout">
|
<StackLayout x:Name="biAnVaLayout">
|
||||||
<ListView x:Name="BillListView" ItemsSource="{Binding Bill}"
|
<ListView x:Name="BillListView" ItemsSource="{Binding Bill}"
|
||||||
MinimumHeightRequest="40" HasUnevenRows="true" VerticalOptions="FillAndExpand"
|
MinimumHeightRequest="40" HasUnevenRows="true" VerticalOptions="FillAndExpand"
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using Xamarin.Forms;
|
||||||
|
|
||||||
namespace BookAStar.Pages
|
namespace BookAStar.Pages
|
||||||
{
|
{
|
||||||
|
using Data;
|
||||||
using Model.Workflow;
|
using Model.Workflow;
|
||||||
using ViewModels;
|
using ViewModels;
|
||||||
public partial class EditEstimatePage : ContentPage
|
public partial class EditEstimatePage : ContentPage
|
||||||
|
|
@ -13,6 +14,16 @@ namespace BookAStar.Pages
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
BindingContext = model;
|
BindingContext = model;
|
||||||
}
|
}
|
||||||
|
protected override void OnBindingContextChanged()
|
||||||
|
{
|
||||||
|
base.OnBindingContextChanged();
|
||||||
|
((EditEstimateViewModel)BindingContext).PropertyChanged += EditEstimatePage_PropertyChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EditEstimatePage_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
DataManager.Current.EstimationCache.SaveCollection();
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnSizeAllocated(double width, double height)
|
protected override void OnSizeAllocated(double width, double height)
|
||||||
{
|
{
|
||||||
|
|
@ -45,7 +56,16 @@ namespace BookAStar.Pages
|
||||||
|
|
||||||
protected void OnEstimateValidated(object sender, EventArgs e)
|
protected void OnEstimateValidated(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var evm = (EditEstimateViewModel)BindingContext;
|
||||||
|
if (evm.State == LocalState.New)
|
||||||
|
{
|
||||||
|
DataManager.Current.Estimates.Create(evm.Data);
|
||||||
|
// we have to manually add this item in our local collection,
|
||||||
|
// since we could prefer to update the whole collection
|
||||||
|
// from server, or whatever other scenario
|
||||||
|
DataManager.Current.Estimates.Add(evm.Data);
|
||||||
|
evm.State = LocalState.UpToDate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ using XLabs.Forms.Mvvm;
|
||||||
|
|
||||||
namespace BookAStar.ViewModels
|
namespace BookAStar.ViewModels
|
||||||
{
|
{
|
||||||
public class BillingLineViewModel : ViewModel, IBillingLine
|
public class BillingLineViewModel : EditingViewModel, IBillingLine
|
||||||
{
|
{
|
||||||
BillingLine data;
|
BillingLine data;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using BookAStar.Interfaces;
|
using BookAStar.Data;
|
||||||
|
using BookAStar.Interfaces;
|
||||||
using BookAStar.Model;
|
using BookAStar.Model;
|
||||||
using BookAStar.Model.Social;
|
using BookAStar.Model.Social;
|
||||||
using System;
|
using System;
|
||||||
|
|
@ -23,11 +24,34 @@ namespace BookAStar.ViewModels
|
||||||
Location = data.Location;
|
Location = data.Location;
|
||||||
EventDate = data.EventDate;
|
EventDate = data.EventDate;
|
||||||
Previsionnal = data.Previsionnal;
|
Previsionnal = data.Previsionnal;
|
||||||
|
Id = data.Id;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
private BookQueryData data;
|
||||||
|
public BookQueryData Data {
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public ClientProviderInfo Client { get; set; }
|
public ClientProviderInfo Client { get; set; }
|
||||||
public Location Location { get; set; }
|
public Location Location { get; set; }
|
||||||
public long Id { get; set; }
|
public long Id { get; set; }
|
||||||
public DateTime EventDate { get; set; }
|
public DateTime EventDate { get; set; }
|
||||||
public decimal? Previsionnal { get; set; }
|
public decimal? Previsionnal { get; set; }
|
||||||
|
public EditEstimateViewModel DraftEstimate
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return DataManager.Current.EstimationCache.LocalGet(this.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string EditEstimateButtonText
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return DraftEstimate != null ? "Editer le devis" : "Faire un devis" ;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,32 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using XLabs.Forms.Mvvm;
|
|
||||||
using BookAStar.Model.Workflow;
|
using BookAStar.Model.Workflow;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using BookAStar.Model;
|
using BookAStar.Model;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
using BookAStar.Data;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace BookAStar.ViewModels
|
namespace BookAStar.ViewModels
|
||||||
{
|
{
|
||||||
public class EditEstimateViewModel : ViewModel
|
public class EditEstimateViewModel : EditingViewModel
|
||||||
{
|
{
|
||||||
public EditEstimateViewModel(Estimate data)
|
/// <summary>
|
||||||
|
/// For deserialization
|
||||||
|
/// </summary>
|
||||||
|
public EditEstimateViewModel()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Builds a new view model on estimate,
|
||||||
|
/// sets <c>Data</c> with given value parameter
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
/// <param name="localState"></param>
|
||||||
|
public EditEstimateViewModel(Estimate data, LocalState localState )
|
||||||
{
|
{
|
||||||
Data = data;
|
Data = data;
|
||||||
if (data.AttachedFiles == null) data.AttachedFiles = new List<string>();
|
State = localState;
|
||||||
if (data.AttachedGraphics == null) data.AttachedGraphics = new List<string>();
|
|
||||||
if (data.Bill == null) data.Bill = new List<BillingLine>();
|
|
||||||
AttachedFiles = new ObservableCollection<string>(data.AttachedFiles);
|
|
||||||
AttachedGraphicList = new ObservableCollection<string>(data.AttachedGraphics);
|
|
||||||
Bill = new ObservableCollection<BillingLine>(data.Bill);
|
|
||||||
Bill.CollectionChanged += Bill_CollectionChanged;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Bill_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
private void Bill_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||||||
|
|
@ -26,19 +34,31 @@ namespace BookAStar.ViewModels
|
||||||
Data.Bill = Bill;
|
Data.Bill = Bill;
|
||||||
NotifyPropertyChanged("FormattedTotal");
|
NotifyPropertyChanged("FormattedTotal");
|
||||||
}
|
}
|
||||||
|
private Estimate data;
|
||||||
|
public Estimate Data { get { return data; } set {
|
||||||
|
data = value;
|
||||||
|
if (data.AttachedFiles == null) data.AttachedFiles = new List<string>();
|
||||||
|
if (data.AttachedGraphics == null) data.AttachedGraphics = new List<string>();
|
||||||
|
if (data.Bill == null) data.Bill = new List<BillingLine>();
|
||||||
|
AttachedFiles = new ObservableCollection<string>(data.AttachedFiles);
|
||||||
|
AttachedGraphicList = new ObservableCollection<string>(data.AttachedGraphics);
|
||||||
|
Bill = new ObservableCollection<BillingLine>(data.Bill);
|
||||||
|
Bill.CollectionChanged += Bill_CollectionChanged;
|
||||||
|
} }
|
||||||
|
|
||||||
public Estimate Data { get; protected set; }
|
[JsonIgnore]
|
||||||
|
|
||||||
public ObservableCollection<string> AttachedFiles
|
public ObservableCollection<string> AttachedFiles
|
||||||
{
|
{
|
||||||
get; protected set;
|
get; protected set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
public ObservableCollection<string> AttachedGraphicList
|
public ObservableCollection<string> AttachedGraphicList
|
||||||
{
|
{
|
||||||
get; protected set;
|
get; protected set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
public ObservableCollection<BillingLine> Bill
|
public ObservableCollection<BillingLine> Bill
|
||||||
{
|
{
|
||||||
get; protected set;
|
get; protected set;
|
||||||
|
|
@ -46,6 +66,7 @@ namespace BookAStar.ViewModels
|
||||||
|
|
||||||
|
|
||||||
string newDesc;
|
string newDesc;
|
||||||
|
[JsonIgnore]
|
||||||
public string Description
|
public string Description
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
@ -61,6 +82,7 @@ namespace BookAStar.ViewModels
|
||||||
}
|
}
|
||||||
|
|
||||||
private int? status;
|
private int? status;
|
||||||
|
[JsonIgnore]
|
||||||
public int? Status
|
public int? Status
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
@ -75,6 +97,7 @@ namespace BookAStar.ViewModels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private string title;
|
private string title;
|
||||||
|
[JsonIgnore]
|
||||||
public string Title
|
public string Title
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
@ -89,10 +112,13 @@ namespace BookAStar.ViewModels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
public ClientProviderInfo Client { get { return Data.Client; } }
|
public ClientProviderInfo Client { get { return Data.Client; } }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
public BookQueryData Query { get { return Data.Query; } }
|
public BookQueryData Query { get { return Data.Query; } }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
public FormattedString FormattedTotal
|
public FormattedString FormattedTotal
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
||||||
29
BookAStar/BookAStar/ViewModels/EditingViewModel.cs
Normal file
29
BookAStar/BookAStar/ViewModels/EditingViewModel.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
using BookAStar.Data;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using XLabs.Forms.Mvvm;
|
||||||
|
|
||||||
|
namespace BookAStar.ViewModels
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Used to make the DataManager know how
|
||||||
|
/// to sync local and remote data
|
||||||
|
/// </summary>
|
||||||
|
public class EditingViewModel: ViewModel
|
||||||
|
{
|
||||||
|
private LocalState state;
|
||||||
|
public LocalState State {
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
base.SetProperty<LocalState>(ref state, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -33,12 +33,11 @@ namespace BookAStar.Views
|
||||||
if (Modified != null)
|
if (Modified != null)
|
||||||
{
|
{
|
||||||
Modified.Invoke(this, new EventArgs());
|
Modified.Invoke(this, new EventArgs());
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private bool editable;
|
|
||||||
public bool Editable
|
public bool Editable
|
||||||
{
|
{
|
||||||
get {
|
get {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue