Fixing: Android: Binding UpdateSourceTrigger with LostFocus crashes the app

Fixing: Binding UpdateSource/TargetTrigger set manually does not overwrite default value of event
Adding missing System.Runtime and System.Threading.Tasks references to Android
V5.2.1
This commit is contained in:
Laurent Bugnion 2015-10-18 22:16:16 +02:00
Родитель 0132cfe17c
Коммит 7d8ac1ec1e
8 изменённых файлов: 154 добавлений и 30 удалений

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

@ -30,4 +30,4 @@ using System.Runtime.InteropServices;
[assembly: CLSCompliant(true)] [assembly: CLSCompliant(true)]
// BL0035 // BL0035
[assembly: AssemblyVersion("5.2.0.*")] [assembly: AssemblyVersion("5.2.1.*")]

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

@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013 # Visual Studio 14
VisualStudioVersion = 12.0.31101.0 VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GalaSoft.MvvmLight (PCL)", "GalaSoft.MvvmLight (PCL)\GalaSoft.MvvmLight (PCL).csproj", "{6A912701-3BA1-4975-ADBF-160CAF66B640}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GalaSoft.MvvmLight (PCL)", "GalaSoft.MvvmLight (PCL)\GalaSoft.MvvmLight (PCL).csproj", "{6A912701-3BA1-4975-ADBF-160CAF66B640}"
EndProject EndProject

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

@ -40,4 +40,4 @@ using System.Runtime.InteropServices;
[assembly:NeutralResourcesLanguage("en-US")] [assembly:NeutralResourcesLanguage("en-US")]
// BL0035 // BL0035
[assembly: AssemblyVersion("5.2.0.*")] [assembly: AssemblyVersion("5.2.1.*")]

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

@ -15,6 +15,7 @@
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile> <AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk> <AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
<TargetFrameworkVersion>v5.1</TargetFrameworkVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@ -42,6 +43,8 @@
<Reference Include="mscorlib" /> <Reference Include="mscorlib" />
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Runtime" />
<Reference Include="System.Threading.Tasks" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>

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

@ -20,8 +20,8 @@ using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Reflection; using System.Reflection;
using System.Windows; using System.Windows;
#if ANDROID #if ANDROID
using Android.Views;
using Android.Text; using Android.Text;
using Android.Widget; using Android.Widget;
#endif #endif
@ -44,10 +44,10 @@ namespace GalaSoft.MvvmLight.Helpers
{ {
private readonly SimpleConverter _converter = new SimpleConverter(); private readonly SimpleConverter _converter = new SimpleConverter();
private readonly List<IWeakEventListener> _listeners = new List<IWeakEventListener>(); private readonly List<IWeakEventListener> _listeners = new List<IWeakEventListener>();
private readonly Dictionary<string, Delegate> _sourceHandlers = new Dictionary<string, Delegate>(); private readonly Dictionary<string, DelegateInfo> _sourceHandlers = new Dictionary<string, DelegateInfo>();
private readonly Expression<Func<TSource>> _sourcePropertyExpression; private readonly Expression<Func<TSource>> _sourcePropertyExpression;
private readonly string _sourcePropertyName; private readonly string _sourcePropertyName;
private readonly Dictionary<string, Delegate> _targetHandlers = new Dictionary<string, Delegate>(); private readonly Dictionary<string, DelegateInfo> _targetHandlers = new Dictionary<string, DelegateInfo>();
private readonly Expression<Func<TTarget>> _targetPropertyExpression; private readonly Expression<Func<TTarget>> _targetPropertyExpression;
private readonly string _targetPropertyName; private readonly string _targetPropertyName;
private WeakAction _onSourceUpdate; private WeakAction _onSourceUpdate;
@ -210,7 +210,8 @@ namespace GalaSoft.MvvmLight.Helpers
_listeners.Clear(); _listeners.Clear();
DetachHandlers(); DetachSourceHandlers();
DetachTargetHandlers();
} }
/// <summary> /// <summary>
@ -337,7 +338,27 @@ namespace GalaSoft.MvvmLight.Helpers
// TODO Do we need weak events here? // TODO Do we need weak events here?
EventHandler handler = HandleSourceEvent; EventHandler handler = HandleSourceEvent;
_sourceHandlers.Add(eventName, handler);
var defaultHandlerInfo = _sourceHandlers.Values.FirstOrDefault(i => i.IsDefault);
if (defaultHandlerInfo != null)
{
DetachSourceHandlers();
}
var info = new DelegateInfo
{
Delegate = handler
};
if (_sourceHandlers.ContainsKey(eventName))
{
_sourceHandlers[eventName] = info;
}
else
{
_sourceHandlers.Add(eventName, info);
}
ev.AddEventHandler( ev.AddEventHandler(
_propertySource.Target, _propertySource.Target,
@ -431,7 +452,13 @@ namespace GalaSoft.MvvmLight.Helpers
switch (mode) switch (mode)
{ {
case UpdateTriggerMode.LostFocus: case UpdateTriggerMode.LostFocus:
return UpdateSourceTrigger("FocusChanged"); #if ANDROID
return UpdateSourceTrigger<View.FocusChangeEventArgs>("FocusChange");
#else
throw new ArgumentException(
"UpdateTriggerMode.LostFocus is only supported in Android at this time",
"mode");
#endif
case UpdateTriggerMode.PropertyChanged: case UpdateTriggerMode.PropertyChanged:
return CheckControlSource(); return CheckControlSource();
@ -498,7 +525,27 @@ namespace GalaSoft.MvvmLight.Helpers
// TODO Do we need weak events here? // TODO Do we need weak events here?
EventHandler<TEventArgs> handler = HandleSourceEvent; EventHandler<TEventArgs> handler = HandleSourceEvent;
_sourceHandlers.Add(eventName, handler);
var defaultHandlerInfo = _sourceHandlers.Values.FirstOrDefault(i => i.IsDefault);
if (defaultHandlerInfo != null)
{
DetachSourceHandlers();
}
var info = new DelegateInfo
{
Delegate = handler
};
if (_sourceHandlers.ContainsKey(eventName))
{
_sourceHandlers[eventName] = info;
}
else
{
_sourceHandlers.Add(eventName, info);
}
ev.AddEventHandler( ev.AddEventHandler(
_propertySource.Target, _propertySource.Target,
@ -592,7 +639,13 @@ namespace GalaSoft.MvvmLight.Helpers
switch (mode) switch (mode)
{ {
case UpdateTriggerMode.LostFocus: case UpdateTriggerMode.LostFocus:
return UpdateTargetTrigger("FocusChanged"); #if ANDROID
return UpdateTargetTrigger<View.FocusChangeEventArgs>("FocusChange");
#else
throw new ArgumentException(
"UpdateTriggerMode.LostFocus is only supported in Android at this time",
"mode");
#endif
case UpdateTriggerMode.PropertyChanged: case UpdateTriggerMode.PropertyChanged:
return CheckControlTarget(); return CheckControlTarget();
@ -662,7 +715,27 @@ namespace GalaSoft.MvvmLight.Helpers
// TODO Do we need weak events here? // TODO Do we need weak events here?
EventHandler handler = HandleTargetEvent; EventHandler handler = HandleTargetEvent;
_targetHandlers.Add(eventName, handler);
var defaultHandlerInfo = _targetHandlers.Values.FirstOrDefault(i => i.IsDefault);
if (defaultHandlerInfo != null)
{
DetachTargetHandlers();
}
var info = new DelegateInfo
{
Delegate = handler
};
if (_targetHandlers.ContainsKey(eventName))
{
_targetHandlers[eventName] = info;
}
else
{
_targetHandlers.Add(eventName, info);
}
ev.AddEventHandler( ev.AddEventHandler(
_propertyTarget.Target, _propertyTarget.Target,
@ -734,7 +807,27 @@ namespace GalaSoft.MvvmLight.Helpers
// TODO Do we need weak events here? // TODO Do we need weak events here?
EventHandler<TEventArgs> handler = HandleTargetEvent; EventHandler<TEventArgs> handler = HandleTargetEvent;
_targetHandlers.Add(eventName, handler);
var defaultHandlerInfo = _targetHandlers.Values.FirstOrDefault(i => i.IsDefault);
if (defaultHandlerInfo != null)
{
DetachTargetHandlers();
}
var info = new DelegateInfo
{
Delegate = handler
};
if (_targetHandlers.ContainsKey(eventName))
{
_targetHandlers[eventName] = info;
}
else
{
_targetHandlers.Add(eventName, info);
}
ev.AddEventHandler( ev.AddEventHandler(
_propertyTarget.Target, _propertyTarget.Target,
@ -1068,13 +1161,17 @@ namespace GalaSoft.MvvmLight.Helpers
var textBox = _propertySource.Target as EditText; var textBox = _propertySource.Target as EditText;
if (textBox != null) if (textBox != null)
{ {
return UpdateSourceTrigger<TextChangedEventArgs>("TextChanged"); var binding = UpdateSourceTrigger<TextChangedEventArgs>("TextChanged");
binding._sourceHandlers["TextChanged"].IsDefault = true;
return binding;
} }
var checkbox = _propertySource.Target as CompoundButton; var checkbox = _propertySource.Target as CompoundButton;
if (checkbox != null) if (checkbox != null)
{ {
return UpdateSourceTrigger<CompoundButton.CheckedChangeEventArgs>("CheckedChange"); var binding = UpdateSourceTrigger<CompoundButton.CheckedChangeEventArgs>("CheckedChange");
binding._sourceHandlers["CheckedChange"].IsDefault = true;
return binding;
} }
return this; return this;
@ -1096,13 +1193,17 @@ namespace GalaSoft.MvvmLight.Helpers
var textBox = _propertyTarget.Target as EditText; var textBox = _propertyTarget.Target as EditText;
if (textBox != null) if (textBox != null)
{ {
return UpdateTargetTrigger<TextChangedEventArgs>("TextChanged"); var binding = UpdateTargetTrigger<TextChangedEventArgs>("TextChanged");
binding._targetHandlers["TextChanged"].IsDefault = true;
return binding;
} }
var checkbox = _propertyTarget.Target as CompoundButton; var checkbox = _propertyTarget.Target as CompoundButton;
if (checkbox != null) if (checkbox != null)
{ {
return UpdateTargetTrigger<CompoundButton.CheckedChangeEventArgs>("CheckedChange"); var binding = UpdateTargetTrigger<CompoundButton.CheckedChangeEventArgs>("CheckedChange");
binding._targetHandlers["CheckedChange"].IsDefault = true;
return binding;
} }
return this; return this;
@ -1113,7 +1214,7 @@ namespace GalaSoft.MvvmLight.Helpers
#endif #endif
} }
private void DetachHandlers() private void DetachSourceHandlers()
{ {
if (_propertySource == null if (_propertySource == null
|| !_propertySource.IsAlive || !_propertySource.IsAlive
@ -1131,7 +1232,19 @@ namespace GalaSoft.MvvmLight.Helpers
return; return;
} }
ev.RemoveEventHandler(_propertySource.Target, _sourceHandlers[eventName]); ev.RemoveEventHandler(_propertySource.Target, _sourceHandlers[eventName].Delegate);
}
_sourceHandlers.Clear();
}
private void DetachTargetHandlers()
{
if (_propertySource == null
|| !_propertySource.IsAlive
|| _propertySource.Target == null)
{
return;
} }
foreach (var eventName in _targetHandlers.Keys) foreach (var eventName in _targetHandlers.Keys)
@ -1143,8 +1256,10 @@ namespace GalaSoft.MvvmLight.Helpers
return; return;
} }
ev.RemoveEventHandler(_propertyTarget.Target, _targetHandlers[eventName]); ev.RemoveEventHandler(_propertyTarget.Target, _targetHandlers[eventName].Delegate);
} }
_targetHandlers.Clear();
} }
private TTarget GetSourceValue() private TTarget GetSourceValue()
@ -1380,5 +1495,11 @@ namespace GalaSoft.MvvmLight.Helpers
_convertBack = new WeakFunc<TTarget, TSource>(convertBack); _convertBack = new WeakFunc<TTarget, TSource>(convertBack);
} }
} }
private class DelegateInfo
{
public Delegate Delegate;
public bool IsDefault;
}
} }
} }

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

@ -2,7 +2,7 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by a tool. // This code was generated by a tool.
// Runtime Version:4.0.30319.0 // Runtime Version:4.0.30319.42000
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.

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

@ -47,4 +47,4 @@ using System.Windows.Markup;
[assembly:NeutralResourcesLanguage("en-US")] [assembly:NeutralResourcesLanguage("en-US")]
// BL0035 // BL0035
[assembly: AssemblyVersion("5.2.0.*")] [assembly: AssemblyVersion("5.2.1.*")]

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

@ -37,25 +37,25 @@
<DocumentationFile>bin\iPhone\Release\GalaSoft.MvvmLight.Platform.XML</DocumentationFile> <DocumentationFile>bin\iPhone\Release\GalaSoft.MvvmLight.Platform.XML</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\..\..\..\..\..\..\MvvmLight\Source\GalaSoft.MvvmLight\GalaSoft.MvvmLight.Platform %28Android%29\Helpers\Binding.cs"> <Compile Include="..\GalaSoft.MvvmLight.Platform %28Android%29\Helpers\Binding.cs">
<Link>Helpers\Binding.cs</Link> <Link>Helpers\Binding.cs</Link>
</Compile> </Compile>
<Compile Include="..\..\..\..\..\..\..\MvvmLight\Source\GalaSoft.MvvmLight\GalaSoft.MvvmLight.Platform %28Android%29\Helpers\BindingGeneric.cs"> <Compile Include="..\GalaSoft.MvvmLight.Platform %28Android%29\Helpers\BindingGeneric.cs">
<Link>Helpers\BindingGeneric.cs</Link> <Link>Helpers\BindingGeneric.cs</Link>
</Compile> </Compile>
<Compile Include="..\..\..\..\..\..\..\MvvmLight\Source\GalaSoft.MvvmLight\GalaSoft.MvvmLight.Platform %28Android%29\Helpers\BindingMode.cs"> <Compile Include="..\GalaSoft.MvvmLight.Platform %28Android%29\Helpers\BindingMode.cs">
<Link>Helpers\BindingMode.cs</Link> <Link>Helpers\BindingMode.cs</Link>
</Compile> </Compile>
<Compile Include="..\..\..\..\..\..\..\MvvmLight\Source\GalaSoft.MvvmLight\GalaSoft.MvvmLight.Platform %28Android%29\Helpers\Extensions.cs"> <Compile Include="..\GalaSoft.MvvmLight.Platform %28Android%29\Helpers\Extensions.cs">
<Link>Helpers\Extensions.cs</Link> <Link>Helpers\Extensions.cs</Link>
</Compile> </Compile>
<Compile Include="..\..\..\..\..\..\..\MvvmLight\Source\GalaSoft.MvvmLight\GalaSoft.MvvmLight.Platform %28Android%29\Helpers\IWeakEventListener.cs"> <Compile Include="..\GalaSoft.MvvmLight.Platform %28Android%29\Helpers\IWeakEventListener.cs">
<Link>Helpers\IWeakEventListener.cs</Link> <Link>Helpers\IWeakEventListener.cs</Link>
</Compile> </Compile>
<Compile Include="..\..\..\..\..\..\..\MvvmLight\Source\GalaSoft.MvvmLight\GalaSoft.MvvmLight.Platform %28Android%29\Helpers\PropertyChangedEventManager.cs"> <Compile Include="..\GalaSoft.MvvmLight.Platform %28Android%29\Helpers\PropertyChangedEventManager.cs">
<Link>Helpers\PropertyChangedEventManager.cs</Link> <Link>Helpers\PropertyChangedEventManager.cs</Link>
</Compile> </Compile>
<Compile Include="..\..\..\..\..\..\..\MvvmLight\Source\GalaSoft.MvvmLight\GalaSoft.MvvmLight.Platform %28Android%29\Helpers\UpdateSourceTriggerMode.cs"> <Compile Include="..\GalaSoft.MvvmLight.Platform %28Android%29\Helpers\UpdateSourceTriggerMode.cs">
<Link>Helpers\UpdateSourceTriggerMode.cs</Link> <Link>Helpers\UpdateSourceTriggerMode.cs</Link>
</Compile> </Compile>
<Compile Include="..\GalaSoft.MvvmLight.Platform %28NET45%29\Properties\AssemblyInfo.cs"> <Compile Include="..\GalaSoft.MvvmLight.Platform %28NET45%29\Properties\AssemblyInfo.cs">