This commit is contained in:
Laurent Bugnion 2016-02-11 10:08:53 +01:00
Родитель f690ec2cf0
Коммит 5f183bad19
18 изменённых файлов: 215 добавлений и 200 удалений

Просмотреть файл

@ -49,11 +49,11 @@ namespace GalaSoft.MvvmLight.Helpers
private WeakAction _onSourceUpdate;
private WeakReference _propertySource;
private WeakReference _propertyTarget;
private bool _resolveTopField;
private bool _settingSourceToTarget;
private bool _settingTargetToSource;
private PropertyInfo _sourceProperty;
private PropertyInfo _targetProperty;
private bool _resolveTopField;
/// <summary>
/// Gets or sets the value to use when the binding is unable to return a value. This can happen if one of the
@ -1040,7 +1040,6 @@ namespace GalaSoft.MvvmLight.Helpers
}
catch (TargetException)
{
}
}
else

Просмотреть файл

@ -25,20 +25,20 @@ namespace GalaSoft.MvvmLight.Helpers
/// A default binding is a one way binding.
/// </summary>
Default = 0,
/// <summary>
/// A one time binding. The binding's value will be set when the
/// binding is created but subsequent changes will be ignored/
/// </summary>
OneTime = 1,
/// <summary>
/// A one way binding, where the changes to the source
/// property will update the target property, but changes to the
/// target property don't affect the source property.
/// </summary>
OneWay = 2,
/// <summary>
/// A two way binding, where the changes to the source
/// property will update the target property, and vice versa.

Просмотреть файл

@ -80,8 +80,10 @@ namespace GalaSoft.MvvmLight.Helpers
/// <summary>
/// Creates a <see cref="Binding{TSource, TSource}"/> with a source property but without a target.
/// This type of bindings is useful for the <see cref="SetCommand{TIn, TOut}"/>
/// and <see cref="SetCommand{T, TEventArgs}"/> methods, to use as CommandParameter
/// This type of bindings is useful for the <see cref="SetCommand{T}(object, string, RelayCommand{T}, Binding)"/>,
/// <see cref="SetCommand{T}(object, RelayCommand{T}, Binding)"/>,
/// <see cref="SetCommand{T, TEventArgs}(object, string, RelayCommand{T}, Binding)"/>
/// and <see cref="SetCommand{T, TEventArgs}(object, RelayCommand{T}, Binding)"/> methods, to use as CommandParameter
/// binding.
/// </summary>
/// <param name="source">The source of the binding. If this object implements INotifyPropertyChanged and the

Просмотреть файл

@ -14,8 +14,9 @@
// ****************************************************************************
// ReSharper disable CheckNamespace
namespace System.Windows
// ReSharper restore CheckNamespace
// ReSharper restore CheckNamespace
{
/// <summary>
/// Provides event listening support for classes that expect to receive events
@ -24,6 +25,14 @@ namespace System.Windows
////[ClassInfo(typeof(Binding))]
public interface IWeakEventListener
{
/// <summary>
/// Gets the WeakReference holding the instance that raised the event.
/// </summary>
WeakReference InstanceReference
{
get;
}
/// <summary>
/// Receives events from the centralized event manager.
/// </summary>
@ -36,13 +45,5 @@ namespace System.Windows
/// an event that it does not recognize or handle.
/// </returns>
bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e);
/// <summary>
/// Gets the WeakReference holding the instance that raised the event.
/// </summary>
WeakReference InstanceReference
{
get;
}
}
}

Просмотреть файл

@ -170,10 +170,12 @@ namespace System.Windows
}
var checkInstance =
_list.Any(l => l.Value.Any(i => i.InstanceReference != null
&& i.InstanceReference.IsAlive
&& i.InstanceReference.Target != null
&& i.InstanceReference.Target.Equals(toRemove.InstanceReference.Target)));
_list.Any(
l => l.Value.Any(
i => i.InstanceReference != null
&& i.InstanceReference.IsAlive
&& i.InstanceReference.Target != null
&& i.InstanceReference.Target.Equals(toRemove.InstanceReference.Target)));
if (!checkInstance)
{

Просмотреть файл

@ -16,9 +16,8 @@
using System;
using System.Text;
////using GalaSoft.Utilities.Attributes;
using GalaSoft.MvvmLight.Views;
////using GalaSoft.Utilities.Attributes;
namespace GalaSoft.MvvmLight.Threading
{
@ -38,7 +37,7 @@ namespace GalaSoft.MvvmLight.Threading
/// thread.</param>
// ReSharper disable InconsistentNaming
public static void CheckBeginInvokeOnUI(Action action)
// ReSharper restore InconsistentNaming
// ReSharper restore InconsistentNaming
{
if (action == null)
{
@ -49,18 +48,6 @@ namespace GalaSoft.MvvmLight.Threading
ActivityBase.CurrentActivity.RunOnUiThread(action);
}
private static void CheckDispatcher()
{
if (ActivityBase.CurrentActivity == null)
{
var error = new StringBuilder("The DispatcherHelper cannot be called.");
error.AppendLine();
error.Append("Make sure that your main Activity derives from ActivityBase.");
throw new InvalidOperationException(error.ToString());
}
}
/// <summary>
/// This method is only here for compatibility with
/// other platforms but it doesn't do anything.
@ -76,5 +63,17 @@ namespace GalaSoft.MvvmLight.Threading
public static void Reset()
{
}
private static void CheckDispatcher()
{
if (ActivityBase.CurrentActivity == null)
{
var error = new StringBuilder("The DispatcherHelper cannot be called.");
error.AppendLine();
error.Append("Make sure that your main Activity derives from ActivityBase.");
throw new InvalidOperationException(error.ToString());
}
}
}
}

Просмотреть файл

@ -33,6 +33,18 @@ namespace GalaSoft.MvvmLight.Views
private set;
}
internal string ActivityKey
{
get;
private set;
}
internal static string NextPageKey
{
get;
set;
}
/// <summary>
/// If possible, discards the current page and displays the previous page
/// on the navigation stack.
@ -63,17 +75,5 @@ namespace GalaSoft.MvvmLight.Views
base.OnResume();
}
internal string ActivityKey
{
get;
private set;
}
internal static string NextPageKey
{
get;
set;
}
}
}

Просмотреть файл

@ -56,8 +56,8 @@ namespace GalaSoft.MvvmLight.Views
};
var info = CreateDialog(
message,
title,
message,
title,
buttonText,
null,
callback);
@ -91,9 +91,9 @@ namespace GalaSoft.MvvmLight.Views
};
var info = CreateDialog(
error.Message,
title,
buttonText,
error.Message,
title,
buttonText,
null,
callback);
@ -114,7 +114,7 @@ namespace GalaSoft.MvvmLight.Views
public Task ShowMessage(string message, string title)
{
var info = CreateDialog(
message,
message,
title);
info.Dialog.Show();
@ -147,9 +147,9 @@ namespace GalaSoft.MvvmLight.Views
};
var info = CreateDialog(
message,
title,
buttonText,
message,
title,
buttonText,
null,
callback);
@ -233,29 +233,11 @@ namespace GalaSoft.MvvmLight.Views
AlertDialog dialog = null;
builder.SetPositiveButton(okText ?? "OK", (d, index) =>
{
tcs.TrySetResult(true);
// ReSharper disable AccessToModifiedClosure
if (dialog != null)
builder.SetPositiveButton(
okText ?? "OK",
(d, index) =>
{
dialog.Dismiss();
dialog.Dispose();
}
if (afterHideCallbackWithResponse != null)
{
afterHideCallbackWithResponse(true);
}
// ReSharper restore AccessToModifiedClosure
});
if (cancelText != null)
{
builder.SetNegativeButton(cancelText, (d, index) =>
{
tcs.TrySetResult(false);
tcs.TrySetResult(true);
// ReSharper disable AccessToModifiedClosure
if (dialog != null)
@ -266,21 +248,45 @@ namespace GalaSoft.MvvmLight.Views
if (afterHideCallbackWithResponse != null)
{
afterHideCallbackWithResponse(false);
afterHideCallbackWithResponse(true);
}
// ReSharper restore AccessToModifiedClosure
});
if (cancelText != null)
{
builder.SetNegativeButton(
cancelText,
(d, index) =>
{
tcs.TrySetResult(false);
// ReSharper disable AccessToModifiedClosure
if (dialog != null)
{
dialog.Dismiss();
dialog.Dispose();
}
if (afterHideCallbackWithResponse != null)
{
afterHideCallbackWithResponse(false);
}
// ReSharper restore AccessToModifiedClosure
});
}
builder.SetOnDismissListener(new OnDismissListener(() =>
{
tcs.TrySetResult(false);
builder.SetOnDismissListener(
new OnDismissListener(
() =>
{
tcs.TrySetResult(false);
if (afterHideCallbackWithResponse != null)
{
afterHideCallbackWithResponse(false);
}
}));
if (afterHideCallbackWithResponse != null)
{
afterHideCallbackWithResponse(false);
}
}));
dialog = builder.Create();

Просмотреть файл

@ -50,76 +50,6 @@ namespace GalaSoft.MvvmLight.Views
}
}
/// <summary>
/// If possible, discards the current page and displays the previous page
/// on the navigation stack.
/// </summary>
public void GoBack()
{
ActivityBase.GoBack();
}
/// <summary>
/// Displays a new page corresponding to the given key.
/// Make sure to call the <see cref="Configure"/>
/// method first.
/// </summary>
/// <param name="pageKey">The key corresponding to the page
/// that should be displayed.</param>
/// <exception cref="ArgumentException">When this method is called for
/// a key that has not been configured earlier.</exception>
public void NavigateTo(string pageKey)
{
NavigateTo(pageKey, null);
}
/// <summary>
/// Displays a new page corresponding to the given key,
/// and passes a parameter to the new page.
/// Make sure to call the <see cref="Configure"/>
/// method first.
/// </summary>
/// <param name="pageKey">The key corresponding to the page
/// that should be displayed.</param>
/// <param name="parameter">The parameter that should be passed
/// to the new page.</param>
/// <exception cref="ArgumentException">When this method is called for
/// a key that has not been configured earlier.</exception>
public void NavigateTo(string pageKey, object parameter)
{
if (ActivityBase.CurrentActivity == null)
{
throw new InvalidOperationException("No CurrentActivity found");
}
lock (_pagesByKey)
{
if (!_pagesByKey.ContainsKey(pageKey))
{
throw new ArgumentException(
string.Format(
"No such page: {0}. Did you forget to call NavigationService.Configure?",
pageKey),
"pageKey");
}
var intent = new Intent(ActivityBase.CurrentActivity, _pagesByKey[pageKey]);
if (parameter != null)
{
lock (_parametersByKey)
{
var guid = Guid.NewGuid().ToString();
_parametersByKey.Add(guid, parameter);
intent.PutExtra(ParameterKeyName, guid);
}
}
ActivityBase.CurrentActivity.StartActivity(intent);
ActivityBase.NextPageKey = pageKey;
}
}
/// <summary>
/// Adds a key/page pair to the navigation service.
/// </summary>
@ -192,5 +122,75 @@ namespace GalaSoft.MvvmLight.Views
{
return (T)GetAndRemoveParameter(intent);
}
/// <summary>
/// If possible, discards the current page and displays the previous page
/// on the navigation stack.
/// </summary>
public void GoBack()
{
ActivityBase.GoBack();
}
/// <summary>
/// Displays a new page corresponding to the given key.
/// Make sure to call the <see cref="Configure"/>
/// method first.
/// </summary>
/// <param name="pageKey">The key corresponding to the page
/// that should be displayed.</param>
/// <exception cref="ArgumentException">When this method is called for
/// a key that has not been configured earlier.</exception>
public void NavigateTo(string pageKey)
{
NavigateTo(pageKey, null);
}
/// <summary>
/// Displays a new page corresponding to the given key,
/// and passes a parameter to the new page.
/// Make sure to call the <see cref="Configure"/>
/// method first.
/// </summary>
/// <param name="pageKey">The key corresponding to the page
/// that should be displayed.</param>
/// <param name="parameter">The parameter that should be passed
/// to the new page.</param>
/// <exception cref="ArgumentException">When this method is called for
/// a key that has not been configured earlier.</exception>
public void NavigateTo(string pageKey, object parameter)
{
if (ActivityBase.CurrentActivity == null)
{
throw new InvalidOperationException("No CurrentActivity found");
}
lock (_pagesByKey)
{
if (!_pagesByKey.ContainsKey(pageKey))
{
throw new ArgumentException(
string.Format(
"No such page: {0}. Did you forget to call NavigationService.Configure?",
pageKey),
"pageKey");
}
var intent = new Intent(ActivityBase.CurrentActivity, _pagesByKey[pageKey]);
if (parameter != null)
{
lock (_parametersByKey)
{
var guid = Guid.NewGuid().ToString();
_parametersByKey.Add(guid, parameter);
intent.PutExtra(ParameterKeyName, guid);
}
}
ActivityBase.CurrentActivity.StartActivity(intent);
ActivityBase.NextPageKey = pageKey;
}
}
}
}

Просмотреть файл

@ -55,15 +55,6 @@ namespace GalaSoft.MvvmLight.Helpers
private INotifyCollectionChanged _notifier;
private ObservableTableSource<T> _tableSource;
/// <summary>
/// A reuse identifier for the TableView's cells.
/// </summary>
public string ReuseId
{
get;
set;
}
/// <summary>
/// When set, specifies which animation should be used when rows change.
/// </summary>
@ -183,6 +174,15 @@ namespace GalaSoft.MvvmLight.Helpers
set;
}
/// <summary>
/// A reuse identifier for the TableView's cells.
/// </summary>
public string ReuseId
{
get;
set;
}
/// <summary>
/// Gets the TableView's selected item.
/// Changes to that property's value raise the PropertyChanged event.

Просмотреть файл

@ -16,9 +16,8 @@
using System;
using System.Text;
////using GalaSoft.Utilities.Attributes;
using Foundation;
////using GalaSoft.Utilities.Attributes;
namespace GalaSoft.MvvmLight.Threading
{
@ -51,7 +50,7 @@ namespace GalaSoft.MvvmLight.Threading
/// thread.</param>
// ReSharper disable InconsistentNaming
public static void CheckBeginInvokeOnUI(Action action)
// ReSharper restore InconsistentNaming
// ReSharper restore InconsistentNaming
{
if (action == null)
{
@ -62,18 +61,6 @@ namespace GalaSoft.MvvmLight.Threading
MainThreadContext.InvokeOnMainThread(action);
}
private static void CheckDispatcher()
{
if (MainThreadContext == null)
{
var error = new StringBuilder("The DispatcherHelper is not initialized.");
error.AppendLine();
error.Append("Call DispatcherHelper.Initialize(app) at the end of AppDelegate.FinishedLaunching.");
throw new InvalidOperationException(error.ToString());
}
}
/// <summary>
/// This method should be called once on the UI thread to ensure that
/// the <see cref="MainThreadContext" /> property is initialized.
@ -95,5 +82,17 @@ namespace GalaSoft.MvvmLight.Threading
{
MainThreadContext = null;
}
private static void CheckDispatcher()
{
if (MainThreadContext == null)
{
var error = new StringBuilder("The DispatcherHelper is not initialized.");
error.AppendLine();
error.Append("Call DispatcherHelper.Initialize(app) at the end of AppDelegate.FinishedLaunching.");
throw new InvalidOperationException(error.ToString());
}
}
}
}

Просмотреть файл

@ -21,17 +21,6 @@ namespace GalaSoft.MvvmLight.Views
set;
}
/// <summary>
/// A constructor used when creating managed representations of unmanaged objects;
/// Called by the runtime.
/// </summary>
/// <param name="handle">Pointer (handle) to the unmanaged object.</param>
/// <remarks>Check the remarks on <see cref="UIViewController(IntPtr)"/></remarks>
protected internal ControllerBase(IntPtr handle)
: base(handle)
{
}
/// <summary>
/// A constructor that initializes the object from the data stored in the unarchiver
/// object.
@ -74,5 +63,16 @@ namespace GalaSoft.MvvmLight.Views
public ControllerBase()
{
}
/// <summary>
/// A constructor used when creating managed representations of unmanaged objects;
/// Called by the runtime.
/// </summary>
/// <param name="handle">Pointer (handle) to the unmanaged object.</param>
/// <remarks>Check the remarks on <see cref="UIViewController(IntPtr)"/></remarks>
protected internal ControllerBase(IntPtr handle)
: base(handle)
{
}
}
}

Просмотреть файл

@ -207,7 +207,7 @@ namespace GalaSoft.MvvmLight.Views
title,
message,
null,
buttonCancelText,
buttonCancelText,
buttonConfirmText);
av.Dismissed += (s, e) =>

Просмотреть файл

@ -1,17 +1,20 @@
using GalaSoft.MvvmLight.Helpers;
using System.Diagnostics.CodeAnalysis;
using GalaSoft.MvvmLight.Helpers;
using GalaSoft.MvvmLight.Test.ViewModel;
using NUnit.Framework;
#if ANDROID
using Android.App;
using Android.Widget;
#elif __IOS__
using UIKit;
#endif
namespace GalaSoft.MvvmLight.Test.Binding
{
[TestFixture]
[SuppressMessage("ReSharper", "InconsistentNaming")]
public class BindingAccountTest
{
private Binding<string, string> _binding1;

Просмотреть файл

@ -3,12 +3,13 @@ using System.Diagnostics.CodeAnalysis;
using GalaSoft.MvvmLight.Helpers;
using GalaSoft.MvvmLight.Test.ViewModel;
using NUnit.Framework;
#if ANDROID
using Android.App;
using Android.Widget;
#elif __IOS__
using GalaSoft.MvvmLight.Test.Controls;
#endif
namespace GalaSoft.MvvmLight.Test.Binding

Просмотреть файл

@ -3,12 +3,13 @@ using System.Diagnostics.CodeAnalysis;
using GalaSoft.MvvmLight.Helpers;
using GalaSoft.MvvmLight.Test.ViewModel;
using NUnit.Framework;
#if ANDROID
using Android.App;
using Android.Widget;
#elif __IOS__
using GalaSoft.MvvmLight.Test.Controls;
#endif
namespace GalaSoft.MvvmLight.Test.Binding

Просмотреть файл

@ -3,13 +3,14 @@ using System.Diagnostics.CodeAnalysis;
using GalaSoft.MvvmLight.Helpers;
using GalaSoft.MvvmLight.Test.ViewModel;
using NUnit.Framework;
#if ANDROID
using Android.App;
using Android.Widget;
#elif __IOS__
using GalaSoft.MvvmLight.Test.Controls;
using UIKit;
#endif
namespace GalaSoft.MvvmLight.Test.Binding
@ -99,6 +100,7 @@ namespace GalaSoft.MvvmLight.Test.Binding
[Test]
public void
Binding_MultipleLevelsOfNullWithConverter_ShouldCallConverterWithNullThenTargetNullValueButNotFallbackValue(
)
{
var vmSource = new TestViewModel();

Просмотреть файл

@ -4,13 +4,13 @@ using System.Globalization;
using GalaSoft.MvvmLight.Helpers;
using GalaSoft.MvvmLight.Test.ViewModel;
using NUnit.Framework;
#if ANDROID
using Android.App;
using Android.Widget;
#elif __IOS__
using GalaSoft.MvvmLight.Test.Controls;
using UIKit;
#endif
namespace GalaSoft.MvvmLight.Test.Binding