Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/xamarin/Xamarin.PropertyEditing.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Maupin <ermaup@microsoft.com>2019-04-24 21:13:36 +0300
committerEric Maupin <ermaup@microsoft.com>2019-04-24 21:13:36 +0300
commitad499d8c9312e7f1c211af8c89eac3cf4cb93018 (patch)
tree2be456d6d5b606c0e9c8b43e9eb60342b4c5b2c7
parentc004b45395ffd9c012ece8bd6b66f8f4f2c33f4f (diff)
-rw-r--r--Xamarin.PropertyEditing.Tests/MockBindingProvider.cs37
-rw-r--r--Xamarin.PropertyEditing.Windows/CreateBindingWindow.xaml6
-rw-r--r--Xamarin.PropertyEditing.Windows/CreateBindingWindow.xaml.cs8
-rw-r--r--Xamarin.PropertyEditing.Windows/PropertyButton.cs2
-rw-r--r--Xamarin.PropertyEditing.Windows/TreeViewItemEx.cs68
-rw-r--r--Xamarin.PropertyEditing.Windows/XamlHelper.cs16
-rw-r--r--Xamarin.PropertyEditing/ViewModels/CreateBindingViewModel.cs29
-rw-r--r--Xamarin.PropertyEditing/ViewModels/EventViewModel.cs2
-rw-r--r--Xamarin.PropertyEditing/ViewModels/ObjectTreeElement.cs13
-rw-r--r--Xamarin.PropertyEditing/ViewModels/PropertyViewModel.cs2
10 files changed, 150 insertions, 33 deletions
diff --git a/Xamarin.PropertyEditing.Tests/MockBindingProvider.cs b/Xamarin.PropertyEditing.Tests/MockBindingProvider.cs
index 8077ed4..67c3e1c 100644
--- a/Xamarin.PropertyEditing.Tests/MockBindingProvider.cs
+++ b/Xamarin.PropertyEditing.Tests/MockBindingProvider.cs
@@ -61,7 +61,7 @@ namespace Xamarin.PropertyEditing.Tests
private static readonly BindingSource StaticResource = new BindingSource ("StaticResource", BindingSourceType.Resource);
private class BindingSourceInstance
- : BindingSource
+ : BindingSource, IEquatable<BindingSourceInstance>
{
public BindingSourceInstance (BindingSource original, string description)
: base (original.Name, original.Type, description)
@@ -73,6 +73,41 @@ namespace Xamarin.PropertyEditing.Tests
{
get;
}
+
+ public override bool Equals (object obj)
+ {
+ if (ReferenceEquals (null, obj))
+ return false;
+ if (ReferenceEquals (this, obj))
+ return true;
+ if (obj.GetType () != GetType ())
+ return false;
+ return Equals ((BindingSourceInstance) obj);
+ }
+
+ public bool Equals (BindingSourceInstance other)
+ {
+ if (ReferenceEquals (null, other))
+ return false;
+ if (ReferenceEquals (this, other))
+ return true;
+ return Original.Equals (other.Original);
+ }
+
+ public override int GetHashCode ()
+ {
+ return Original.GetHashCode ();
+ }
+
+ public static bool operator == (BindingSourceInstance left, BindingSourceInstance right)
+ {
+ return Equals (left, right);
+ }
+
+ public static bool operator != (BindingSourceInstance left, BindingSourceInstance right)
+ {
+ return !Equals (left, right);
+ }
}
}
diff --git a/Xamarin.PropertyEditing.Windows/CreateBindingWindow.xaml b/Xamarin.PropertyEditing.Windows/CreateBindingWindow.xaml
index d233dc4..a6ce330 100644
--- a/Xamarin.PropertyEditing.Windows/CreateBindingWindow.xaml
+++ b/Xamarin.PropertyEditing.Windows/CreateBindingWindow.xaml
@@ -120,7 +120,7 @@
<local:TextBoxEx Grid.Row="3" Grid.Column="2" VerticalAlignment="Top" Margin="0,4,0,4" Visibility="{Binding ElementName=content,Path=IsChecked,Converter={StaticResource BoolToVisibilityConverter}}" Text="{Binding Path,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Name="longDescription" Grid.Row="3" Grid.RowSpan="2" Grid.Column="0" VerticalAlignment="Stretch" Text="{Binding SelectedBindingSource.Description}" Visibility="{Binding ShowLongDescription,Converter={StaticResource BoolToVisibilityConverter}}" />
- <local:TreeViewEx Grid.Row="3" Grid.RowSpan="2" Grid.Column="0" Margin="0,4,0,0" Style="{DynamicResource SelectionTreeView}" ItemsSource="{Binding ObjectElementRoots.Value}" DisplayMemberPath="Name.Value" Visibility="{Binding ShowObjectSelector,Converter={StaticResource BoolToVisibilityConverter}}" />
+ <local:TreeViewEx Grid.Row="3" Grid.RowSpan="2" Grid.Column="0" Margin="0,4,0,0" Style="{DynamicResource SelectionTreeView}" ItemsSource="{Binding ObjectElementRoots.Value}" DisplayMemberPath="Name.Value" Visibility="{Binding ShowObjectSelector,Converter={StaticResource BoolToVisibilityConverter}}" SelectedDataItem="{Binding SelectedObjectTreeElement,Mode=TwoWay}" />
<local:TreeViewEx Grid.Row="3" Grid.RowSpan="2" Grid.Column="0" Margin="0,4,0,0" Style="{DynamicResource AutoExpandSelectionTreeView}" ItemsSource="{Binding SourceResources.Value}" Visibility="{Binding ShowResourceSelector,Converter={StaticResource BoolToVisibilityConverter}}" SelectedDataItem="{Binding SelectedResource,Mode=TwoWay}">
<local:TreeViewEx.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Mode=OneTime}">
@@ -133,10 +133,10 @@
</HierarchicalDataTemplate>
</local:TreeViewEx.ItemTemplate>
</local:TreeViewEx>
- <local:TypeSelectorControl Grid.Row="3" Grid.RowSpan="2" Grid.Column="0" Margin="0,4,0,0" Visibility="{Binding DataContext.ShowTypeSelector,Converter={StaticResource BoolToVisibilityConverter},ElementName=propertiesTree}" ShowTypeLevel="{Binding DataContext.ShowTypeLevel,ElementName=propertiesTree}" DataContext="{Binding TypeSelector}" TypeLevel="{Binding TypeLevel,Mode=TwoWay}" />
+ <local:TypeSelectorControl Grid.Row="3" Grid.RowSpan="2" Grid.Column="0" Margin="0,4,0,0" Visibility="{Binding DataContext.ShowTypeSelector,Converter={StaticResource BoolToVisibilityConverter},ElementName=propertiesTree}" ShowTypeLevel="{Binding DataContext.ShowTypeLevel,ElementName=propertiesTree}" DataContext="{Binding TypeSelector}" TypeLevel="{Binding TypeLevel,Mode=TwoWay}" />
<local:TreeViewEx x:Name="propertiesTree" Grid.Row="4" Grid.Column="2" Margin="0,4,0,0" Style="{DynamicResource SelectionTreeView}" SelectedDataItem="{Binding SelectedPropertyElement,Mode=TwoWay}">
- <local:TreeViewItemEx Header="{Binding PropertyRoot.Value.TargetType.Name}" IsExpanded="True" ItemsSource="{Binding PropertyRoot.Value.Children}" ItemContainerStyle="{DynamicResource SelectionTreeViewItem}">
+ <local:TreeViewItemEx DataContext="{Binding PropertyRoot.Value}" Header="{Binding TargetType.Name}" IsExpanded="True" ItemsSource="{Binding Children}" ItemContainerStyle="{DynamicResource SelectionTreeViewItem}">
<local:TreeViewItemEx.ItemTemplate>
<HierarchicalDataTemplate DataType="vms:PropertyTreeElement" ItemsSource="{Binding Children.Value}">
<TextBlock>
diff --git a/Xamarin.PropertyEditing.Windows/CreateBindingWindow.xaml.cs b/Xamarin.PropertyEditing.Windows/CreateBindingWindow.xaml.cs
index 72ea59d..f60630b 100644
--- a/Xamarin.PropertyEditing.Windows/CreateBindingWindow.xaml.cs
+++ b/Xamarin.PropertyEditing.Windows/CreateBindingWindow.xaml.cs
@@ -12,9 +12,9 @@ namespace Xamarin.PropertyEditing.Windows
internal partial class CreateBindingWindow
: WindowEx
{
- public CreateBindingWindow (IEnumerable<ResourceDictionary> merged, TargetPlatform platform, IObjectEditor editor, IPropertyInfo property)
+ public CreateBindingWindow (IEnumerable<ResourceDictionary> merged, TargetPlatform platform, IObjectEditor editor, IPropertyInfo property, PropertyVariation variation = null, object bindingObject = null)
{
- var vm = new CreateBindingViewModel (platform, editor, property);
+ var vm = new CreateBindingViewModel (platform, editor, property, variation, bindingObject);
vm.CreateValueConverterRequested += OnCreateValueConverterRequested;
DataContext = vm;
@@ -49,10 +49,10 @@ namespace Xamarin.PropertyEditing.Windows
DialogResult = false;
}
- internal static object CreateBinding (FrameworkElement owner, TargetPlatform platform, IObjectEditor editor, IPropertyInfo property)
+ internal static object CreateBinding (FrameworkElement owner, TargetPlatform platform, IObjectEditor editor, IPropertyInfo property, PropertyVariation variation = null, object bindingObject = null)
{
Window ownerWindow = Window.GetWindow (owner);
- var window = new CreateBindingWindow (owner.Resources.MergedDictionaries, platform, editor, property) {
+ var window = new CreateBindingWindow (owner.Resources.MergedDictionaries, platform, editor, property, variation, bindingObject) {
Owner = ownerWindow
};
bool? result = window.ShowDialog ();
diff --git a/Xamarin.PropertyEditing.Windows/PropertyButton.cs b/Xamarin.PropertyEditing.Windows/PropertyButton.cs
index 89434de..bf5ecb1 100644
--- a/Xamarin.PropertyEditing.Windows/PropertyButton.cs
+++ b/Xamarin.PropertyEditing.Windows/PropertyButton.cs
@@ -162,7 +162,7 @@ namespace Xamarin.PropertyEditing.Windows
var panel = this.FindPropertiesHost ();
var pvm = (PropertyViewModel) DataContext;
- e.BindingObject = CreateBindingWindow.CreateBinding (panel, pvm.TargetPlatform, pvm.Editors.Single(), pvm.Property);
+ e.BindingObject = CreateBindingWindow.CreateBinding (panel, pvm.TargetPlatform, pvm.Editors.Single(), pvm.Property, pvm.Variation, e.BindingObject);
}
private void OnResourceRequested (object sender, ResourceRequestedEventArgs e)
diff --git a/Xamarin.PropertyEditing.Windows/TreeViewItemEx.cs b/Xamarin.PropertyEditing.Windows/TreeViewItemEx.cs
index ef40e26..554979d 100644
--- a/Xamarin.PropertyEditing.Windows/TreeViewItemEx.cs
+++ b/Xamarin.PropertyEditing.Windows/TreeViewItemEx.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
@@ -74,10 +75,29 @@ namespace Xamarin.PropertyEditing.Windows
value.IsSelected = true;
}
- SetSelectedItem (oldItem, value?.DataContext);
- this.fromTreeItem = true;
- SetCurrentValue (SelectedDataItemProperty, value?.DataContext);
- this.fromTreeItem = false;
+ void SetItem (object old, object newItem)
+ {
+ SetSelectedItem (old, newItem);
+ this.fromTreeItem = true;
+ SetCurrentValue (SelectedDataItemProperty, newItem);
+ this.fromTreeItem = false;
+ } // doesn't work
+
+ if (value != null && !value.IsDescendantOf (this)) {
+ RoutedEventHandler loaded = null;
+ loaded = (sender, args) => {
+ if (this.selectedTreeItem == value) {
+ SetItem (oldItem, value.DataContext);
+ }
+
+ value.Loaded -= loaded;
+ };
+
+ value.Loaded += loaded;
+ return;
+ }
+
+ SetItem (oldItem, value?.DataContext);
}
}
@@ -95,6 +115,19 @@ namespace Xamarin.PropertyEditing.Windows
return;
}
+ if (ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated) {
+ EventHandler statusHandler = null;
+ statusHandler = (sender, args) => {
+ if (ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated) {
+ ItemContainerGenerator.StatusChanged -= statusHandler;
+ OnSelectedDataItemChanged();
+ }
+ };
+
+ ItemContainerGenerator.StatusChanged += statusHandler;
+ return;
+ }
+
TreeViewItemEx treeItem = FindItem (ItemContainerGenerator, item);
if (treeItem == null)
return;
@@ -109,17 +142,17 @@ namespace Xamarin.PropertyEditing.Windows
var path = pathProvider.GetItemParents (item);
for (int i = 0; i < path.Count; i++) {
- if (ItemsSource != null) {
- treeItem = (TreeViewItemEx) generator.ContainerFromItem (path[i]);
- } else { // Manual items won't map, despite data contexts
- for (int x = 0; x < generator.Items.Count; x++) {
- if (!(generator.Items[x] is TreeViewItemEx tvi))
- continue;
-
- if (Equals (tvi.DataContext, path[i])) {
- treeItem = tvi;
- break;
- }
+ for (int x = 0; x < generator.Items.Count; x++) {
+ object context = null;
+ object genItem = generator.Items[x];
+ if (genItem is FrameworkElement fe) {
+ context = fe.DataContext;
+ } else
+ context = genItem;
+
+ if (Equals (context, path[i])) {
+ treeItem = (TreeViewItemEx)generator.GetOrCreateContainerFromIndex (x);
+ break;
}
}
@@ -129,6 +162,8 @@ namespace Xamarin.PropertyEditing.Windows
treeItem.IsExpanded = true;
generator = treeItem.ItemContainerGenerator;
}
+
+ return treeItem;
}
// This is a fallback that will fail if virtualized away
@@ -256,6 +291,9 @@ namespace Xamarin.PropertyEditing.Windows
protected override void OnSelected (RoutedEventArgs e)
{
TreeViewEx parent = GetParentTree();
+ if (parent == null)
+ return;
+
if (!IsSelectable) {
IsSelected = false;
e.Handled = true;
diff --git a/Xamarin.PropertyEditing.Windows/XamlHelper.cs b/Xamarin.PropertyEditing.Windows/XamlHelper.cs
index 7f3ac32..b943b80 100644
--- a/Xamarin.PropertyEditing.Windows/XamlHelper.cs
+++ b/Xamarin.PropertyEditing.Windows/XamlHelper.cs
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
using System.Windows.Media;
namespace Xamarin.PropertyEditing.Windows
@@ -74,5 +76,19 @@ namespace Xamarin.PropertyEditing.Windows
return (TParent)parent;
}
+
+ public static DependencyObject GetOrCreateContainerFromIndex (this ItemContainerGenerator self, int index)
+ {
+ DependencyObject treeItem = self.ContainerFromIndex (index);
+ if (treeItem == null && self.Status != GeneratorStatus.ContainersGenerated) {
+ IItemContainerGenerator igen = self;
+ GeneratorPosition pos = igen.GeneratorPositionFromIndex (index);
+ using (igen.StartAt (pos, GeneratorDirection.Forward)) {
+ treeItem = igen.GenerateNext ();
+ }
+ }
+
+ return treeItem;
+ }
}
}
diff --git a/Xamarin.PropertyEditing/ViewModels/CreateBindingViewModel.cs b/Xamarin.PropertyEditing/ViewModels/CreateBindingViewModel.cs
index 63cd5a1..5b199be 100644
--- a/Xamarin.PropertyEditing/ViewModels/CreateBindingViewModel.cs
+++ b/Xamarin.PropertyEditing/ViewModels/CreateBindingViewModel.cs
@@ -727,19 +727,36 @@ namespace Xamarin.PropertyEditing.ViewModels
IReadOnlyList<object> IProvidePath.GetItemParents (object item)
{
+ List<object> path = new List<object> ();
+
switch (item) {
case PropertyTreeElement prop:
- List<object> path = new List<object> ();
- var current = prop;
- while (current != null) {
- path.Insert (0, current);
- current = current.Parent;
+ var currentProp = prop;
+ while (currentProp != null) {
+ path.Insert (0, currentProp);
+ currentProp = currentProp.Parent;
}
path.Insert (0, PropertyRoot.Value);
return path;
+ case ObjectTreeElement obj:
+ var currentObj = obj;
+ while (currentObj != null) {
+ path.Insert (0, currentObj);
+ currentObj = currentObj.Parent;
+ }
+
+ return path;
case Resource resource:
- return new object[] { resource.Source, resource };
+ foreach (var k in SourceResources.Value) {
+ if (k.Key == resource.Source) {
+ path.Add (k);
+ break;
+ }
+ }
+
+ path.Add (resource);
+ return path;
default:
throw new ArgumentException();
}
diff --git a/Xamarin.PropertyEditing/ViewModels/EventViewModel.cs b/Xamarin.PropertyEditing/ViewModels/EventViewModel.cs
index a50eb5f..a233cf8 100644
--- a/Xamarin.PropertyEditing/ViewModels/EventViewModel.cs
+++ b/Xamarin.PropertyEditing/ViewModels/EventViewModel.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
diff --git a/Xamarin.PropertyEditing/ViewModels/ObjectTreeElement.cs b/Xamarin.PropertyEditing/ViewModels/ObjectTreeElement.cs
index 5064ef3..56f22f5 100644
--- a/Xamarin.PropertyEditing/ViewModels/ObjectTreeElement.cs
+++ b/Xamarin.PropertyEditing/ViewModels/ObjectTreeElement.cs
@@ -31,6 +31,12 @@ namespace Xamarin.PropertyEditing.ViewModels
Name = new AsyncValue<string> (nameTask, typeName);
}
+ private ObjectTreeElement (IEditorProvider provider, IObjectEditor editor, ObjectTreeElement parent)
+ : this (provider, editor)
+ {
+ Parent = parent;
+ }
+
public AsyncValue<string> Name
{
get;
@@ -41,6 +47,11 @@ namespace Xamarin.PropertyEditing.ViewModels
get;
}
+ public ObjectTreeElement Parent
+ {
+ get;
+ }
+
public AsyncValue<IReadOnlyList<ObjectTreeElement>> Children
{
get;
@@ -56,7 +67,7 @@ namespace Xamarin.PropertyEditing.ViewModels
}
IObjectEditor[] editors = await Task.WhenAll (editorTasks);
- return editors.Select (e => new ObjectTreeElement (provider, e)).ToArray ();
+ return editors.Select (e => new ObjectTreeElement (provider, e, this)).ToArray ();
}
}
} \ No newline at end of file
diff --git a/Xamarin.PropertyEditing/ViewModels/PropertyViewModel.cs b/Xamarin.PropertyEditing/ViewModels/PropertyViewModel.cs
index 407dbe1..7555fad 100644
--- a/Xamarin.PropertyEditing/ViewModels/PropertyViewModel.cs
+++ b/Xamarin.PropertyEditing/ViewModels/PropertyViewModel.cs
@@ -50,7 +50,7 @@ namespace Xamarin.PropertyEditing.ViewModels
public override ValueSource ValueSource => this.value != null ? this.value.Source : ValueSource.Default;
/// <remarks>
- /// This is only meant for use from the UI. Other value setting mechanisms (like, converting resources to local, or setting to a resource) should
+ /// The setter is only meant for use from the UI. Other value setting mechanisms (like, converting resources to local, or setting to a resource) should
/// use bespoke value setting mechanisms as this property switches the value source to local and only if the value itself has changed.
/// </remarks>
public TValue Value