removed original treeview control as now this is supported in the box with the latest windows sdk
This commit is contained in:
Родитель
67fe322707
Коммит
b33a775123
|
@ -1,33 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "pch.h"
|
|
||||||
#include "IntegerToIndentationConverter.h"
|
|
||||||
|
|
||||||
using namespace Platform;
|
|
||||||
using namespace Windows::UI::Xaml;
|
|
||||||
using namespace Windows::UI::Xaml::Interop;
|
|
||||||
|
|
||||||
namespace TreeViewControl {
|
|
||||||
|
|
||||||
IntegerToIndentationConverter::IntegerToIndentationConverter()
|
|
||||||
{
|
|
||||||
//default
|
|
||||||
indentMultiplier = 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object^ IntegerToIndentationConverter::Convert(Object^ value, TypeName targetType, Object^ parameter, String^ language)
|
|
||||||
{
|
|
||||||
Thickness indent(0);
|
|
||||||
if (value != nullptr)
|
|
||||||
{
|
|
||||||
indent.Left = (int)value * indentMultiplier;
|
|
||||||
return indent;
|
|
||||||
}
|
|
||||||
|
|
||||||
return indent;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object^ IntegerToIndentationConverter::ConvertBack(Object^ value, TypeName targetType, Object^ parameter, String^ language)
|
|
||||||
{
|
|
||||||
throw ref new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace TreeViewControl {
|
|
||||||
[Windows::Foundation::Metadata::WebHostHidden]
|
|
||||||
public ref class IntegerToIndentationConverter sealed : Windows::UI::Xaml::Data::IValueConverter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
property int IndentMultiplier
|
|
||||||
{
|
|
||||||
int get() { return indentMultiplier; };
|
|
||||||
void set(int i) { indentMultiplier = i; };
|
|
||||||
}
|
|
||||||
|
|
||||||
IntegerToIndentationConverter();
|
|
||||||
|
|
||||||
virtual Platform::Object^ Convert(Object^ value, Windows::UI::Xaml::Interop::TypeName targetType, Platform::Object^ parameter, Platform::String^ language);
|
|
||||||
|
|
||||||
virtual Platform::Object^ ConvertBack(Object^ value, Windows::UI::Xaml::Interop::TypeName targetType, Platform::Object^ parameter, Platform::String^ language);
|
|
||||||
private:
|
|
||||||
int indentMultiplier;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,208 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "pch.h"
|
|
||||||
#include "TreeNode.h"
|
|
||||||
|
|
||||||
using namespace Platform;
|
|
||||||
using namespace Platform::Collections;
|
|
||||||
using namespace Windows::UI::Xaml::Data;
|
|
||||||
using namespace Windows::UI::Xaml::Interop;
|
|
||||||
using namespace Windows::Foundation;
|
|
||||||
using namespace Windows::Foundation::Collections;
|
|
||||||
|
|
||||||
namespace TreeViewControl {
|
|
||||||
|
|
||||||
TreeNode::TreeNode()
|
|
||||||
{
|
|
||||||
childrenVector->VectorChanged += ref new VectorChangedEventHandler<TreeNode ^>(this, &TreeNode::ChildrenVectorChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeNode::Append(Object^ value)
|
|
||||||
{
|
|
||||||
int count = childrenVector->Size;
|
|
||||||
TreeNode^ targetNode = (TreeNode^)value;
|
|
||||||
targetNode->ParentNode = this;
|
|
||||||
childrenVector->Append(targetNode);
|
|
||||||
|
|
||||||
//If the count was 0 before we appended, then the HasItems property needs to change.
|
|
||||||
if (count == 0)
|
|
||||||
{
|
|
||||||
this->PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs("HasItems"));
|
|
||||||
}
|
|
||||||
|
|
||||||
this->PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs("Size"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeNode::Clear()
|
|
||||||
{
|
|
||||||
int count = childrenVector->Size;
|
|
||||||
TreeNode^ childNode;
|
|
||||||
for (int i = 0; i < (int)Size; i++)
|
|
||||||
{
|
|
||||||
childNode = (TreeNode^)GetAt(i);
|
|
||||||
childNode->ParentNode = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
childrenVector->Clear();
|
|
||||||
|
|
||||||
//If the count was not 0 before we cleared, then the HasItems property needs to change.
|
|
||||||
if (count != 0)
|
|
||||||
{
|
|
||||||
this->PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs("HasItems"));
|
|
||||||
}
|
|
||||||
|
|
||||||
this->PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs("Size"));
|
|
||||||
}
|
|
||||||
|
|
||||||
IBindableIterator^ TreeNode::First()
|
|
||||||
{
|
|
||||||
return dynamic_cast<IBindableIterator^>(childrenVector->First());
|
|
||||||
}
|
|
||||||
|
|
||||||
Object^ TreeNode::GetAt(unsigned int index)
|
|
||||||
{
|
|
||||||
if ((int)index > -1 && index < childrenVector->Size)
|
|
||||||
{
|
|
||||||
return childrenVector->GetAt(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
IBindableVectorView^ TreeNode::GetView()
|
|
||||||
{
|
|
||||||
return safe_cast<IBindableVectorView^>(childrenVector->GetView());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TreeNode::IndexOf(Object^ value, unsigned int* index)
|
|
||||||
{
|
|
||||||
return childrenVector->IndexOf((TreeNode^)value, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeNode::InsertAt(unsigned int index, Object^ value)
|
|
||||||
{
|
|
||||||
if ((int)index > -1 && index <= childrenVector->Size)
|
|
||||||
{
|
|
||||||
int count = childrenVector->Size;
|
|
||||||
TreeNode^ targetNode = (TreeNode^)value;
|
|
||||||
targetNode->ParentNode = this;
|
|
||||||
return childrenVector->InsertAt(index, (TreeNode^)value);
|
|
||||||
|
|
||||||
//If the count was 0 before we insert, then the HasItems property needs to change.
|
|
||||||
if (count == 0)
|
|
||||||
{
|
|
||||||
this->PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs("HasItems"));
|
|
||||||
}
|
|
||||||
|
|
||||||
this->PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs("Size"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeNode::RemoveAt(unsigned int index)
|
|
||||||
{
|
|
||||||
if ((int)index > -1 && index < childrenVector->Size)
|
|
||||||
{
|
|
||||||
int count = childrenVector->Size;
|
|
||||||
TreeNode^ targetNode = childrenVector->GetAt(index);
|
|
||||||
targetNode->ParentNode = nullptr;
|
|
||||||
childrenVector->RemoveAt(index);
|
|
||||||
|
|
||||||
//If the count was 1 before we remove, then the HasItems property needs to change.
|
|
||||||
if (count == 1)
|
|
||||||
{
|
|
||||||
this->PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs("HasItems"));
|
|
||||||
}
|
|
||||||
|
|
||||||
this->PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs("Size"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeNode::RemoveAtEnd()
|
|
||||||
{
|
|
||||||
int count = childrenVector->Size;
|
|
||||||
TreeNode^ targetNode = childrenVector->GetAt(childrenVector->Size - 1);
|
|
||||||
targetNode->ParentNode = nullptr;
|
|
||||||
childrenVector->RemoveAtEnd();
|
|
||||||
|
|
||||||
//If the count was 1 before we remove, then the HasItems property needs to change.
|
|
||||||
if (count == 1)
|
|
||||||
{
|
|
||||||
this->PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs("HasItems"));
|
|
||||||
}
|
|
||||||
|
|
||||||
this->PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs("Size"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeNode::SetAt(unsigned int index, Object^ value)
|
|
||||||
{
|
|
||||||
if ((int)index > -1 && index <= childrenVector->Size)
|
|
||||||
{
|
|
||||||
childrenVector->GetAt(index)->ParentNode = nullptr;
|
|
||||||
TreeNode^ targetNode = (TreeNode^)value;
|
|
||||||
targetNode->ParentNode = this;
|
|
||||||
return childrenVector->SetAt(index, targetNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeNode::ChildrenVectorChanged(IObservableVector<TreeNode^>^ sender, IVectorChangedEventArgs^ e)
|
|
||||||
{
|
|
||||||
VectorChanged(this, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int TreeNode::Size::get()
|
|
||||||
{
|
|
||||||
return childrenVector->Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object^ TreeNode::Data::get()
|
|
||||||
{
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeNode::Data::set(Object^ value)
|
|
||||||
{
|
|
||||||
data = value;
|
|
||||||
this->PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs("Data"));
|
|
||||||
}
|
|
||||||
|
|
||||||
TreeNode^ TreeNode::ParentNode::get()
|
|
||||||
{
|
|
||||||
return parentNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeNode::ParentNode::set(TreeNode^ value)
|
|
||||||
{
|
|
||||||
parentNode = value;
|
|
||||||
this->PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs("ParentNode"));
|
|
||||||
this->PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs("Depth"));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TreeNode::IsExpanded::get()
|
|
||||||
{
|
|
||||||
return isExpanded;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeNode::IsExpanded::set(bool value)
|
|
||||||
{
|
|
||||||
isExpanded = value;
|
|
||||||
this->PropertyChanged(this, ref new Windows::UI::Xaml::Data::PropertyChangedEventArgs("IsExpanded"));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TreeNode::HasItems::get()
|
|
||||||
{
|
|
||||||
return (Size != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int TreeNode::Depth::get()
|
|
||||||
{
|
|
||||||
TreeNode^ ancestorNode = this;
|
|
||||||
int depth = -1;
|
|
||||||
while ((ancestorNode->ParentNode) != nullptr)
|
|
||||||
{
|
|
||||||
depth++;
|
|
||||||
ancestorNode = ancestorNode->ParentNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
return depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,100 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace TreeViewControl {
|
|
||||||
/// <summary>
|
|
||||||
/// The TreeNode class implements the hierarchical layout for the TreeView.
|
|
||||||
/// It also holds the data that will be bound to in the item template.
|
|
||||||
/// </summary>
|
|
||||||
[Windows::UI::Xaml::Data::Bindable]
|
|
||||||
[Windows::Foundation::Metadata::WebHostHidden]
|
|
||||||
public ref class TreeNode sealed : Windows::UI::Xaml::Interop::IBindableObservableVector, Windows::UI::Xaml::Data::INotifyPropertyChanged
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TreeNode();
|
|
||||||
|
|
||||||
virtual void Append(Object^ value);
|
|
||||||
|
|
||||||
virtual void Clear();
|
|
||||||
|
|
||||||
virtual Windows::UI::Xaml::Interop::IBindableIterator^ First();
|
|
||||||
|
|
||||||
virtual Object^ GetAt(unsigned int index);
|
|
||||||
|
|
||||||
virtual Windows::UI::Xaml::Interop::IBindableVectorView^ GetView();
|
|
||||||
|
|
||||||
virtual bool IndexOf(Object^ value, unsigned int* index);
|
|
||||||
|
|
||||||
virtual void InsertAt(unsigned int index, Object^ value);
|
|
||||||
|
|
||||||
virtual void RemoveAt(unsigned int index);
|
|
||||||
|
|
||||||
virtual void RemoveAtEnd();
|
|
||||||
|
|
||||||
virtual void SetAt(unsigned int index, Object^ value);
|
|
||||||
|
|
||||||
virtual event Windows::UI::Xaml::Interop::BindableVectorChangedEventHandler^ VectorChanged
|
|
||||||
{
|
|
||||||
virtual Windows::Foundation::EventRegistrationToken add(Windows::UI::Xaml::Interop::BindableVectorChangedEventHandler^ e)
|
|
||||||
{
|
|
||||||
return TreeNodeChanged += e;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void remove(Windows::Foundation::EventRegistrationToken t)
|
|
||||||
{
|
|
||||||
TreeNodeChanged -= t;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal: virtual void raise(Windows::UI::Xaml::Interop::IBindableObservableVector^ vector, Platform::Object^ e)
|
|
||||||
{
|
|
||||||
TreeNodeChanged(vector, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;
|
|
||||||
|
|
||||||
virtual property unsigned int Size
|
|
||||||
{
|
|
||||||
unsigned int get();
|
|
||||||
}
|
|
||||||
|
|
||||||
property Object^ Data
|
|
||||||
{
|
|
||||||
Object^ get();
|
|
||||||
void set(Object^ value);
|
|
||||||
}
|
|
||||||
|
|
||||||
property TreeNode^ ParentNode
|
|
||||||
{
|
|
||||||
TreeNode^ get();
|
|
||||||
void set(TreeNode^ value);
|
|
||||||
}
|
|
||||||
|
|
||||||
property bool IsExpanded
|
|
||||||
{
|
|
||||||
bool get();
|
|
||||||
void set(bool value);
|
|
||||||
}
|
|
||||||
|
|
||||||
property bool HasItems
|
|
||||||
{
|
|
||||||
bool get();
|
|
||||||
}
|
|
||||||
|
|
||||||
//A lone TreeNode will have a depth of -1, this is to show that it is not appended
|
|
||||||
//under the TreeView's invisible root node. Once added into the TreeView via
|
|
||||||
//that method, the depth of the node will be calculated appropriately.
|
|
||||||
property int Depth
|
|
||||||
{
|
|
||||||
int get();
|
|
||||||
}
|
|
||||||
|
|
||||||
event Windows::UI::Xaml::Interop::BindableVectorChangedEventHandler^ TreeNodeChanged;
|
|
||||||
|
|
||||||
private:
|
|
||||||
TreeNode^ parentNode = nullptr;
|
|
||||||
Object^ data = nullptr;
|
|
||||||
bool isExpanded = false;
|
|
||||||
Platform::Collections::Vector<TreeNode^>^ childrenVector = ref new Platform::Collections::Vector<TreeNode^>();
|
|
||||||
void ChildrenVectorChanged(Windows::Foundation::Collections::IObservableVector<TreeNode^>^ sender, Windows::Foundation::Collections::IVectorChangedEventArgs^ e);
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,189 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "pch.h"
|
|
||||||
#include "TreeView.h"
|
|
||||||
|
|
||||||
using namespace Windows::UI::Xaml;
|
|
||||||
using namespace Windows::UI::Xaml::Interop;
|
|
||||||
using namespace Windows::UI::Xaml::Controls;
|
|
||||||
|
|
||||||
namespace TreeViewControl {
|
|
||||||
|
|
||||||
TreeView::TreeView()
|
|
||||||
{
|
|
||||||
flatViewModel = ref new ViewModel;
|
|
||||||
rootNode = ref new TreeNode();
|
|
||||||
|
|
||||||
flatViewModel->ExpandNode(rootNode);
|
|
||||||
|
|
||||||
CanReorderItems = true;
|
|
||||||
AllowDrop = true;
|
|
||||||
CanDragItems = true;
|
|
||||||
|
|
||||||
rootNode->VectorChanged += ref new BindableVectorChangedEventHandler(flatViewModel, &ViewModel::TreeNodeVectorChanged);
|
|
||||||
ItemClick += ref new Windows::UI::Xaml::Controls::ItemClickEventHandler(this, &TreeView::TreeView_OnItemClick);
|
|
||||||
DragItemsStarting += ref new Windows::UI::Xaml::Controls::DragItemsStartingEventHandler(this, &TreeView::TreeView_DragItemsStarting);
|
|
||||||
DragItemsCompleted += ref new Windows::Foundation::TypedEventHandler<Windows::UI::Xaml::Controls::ListViewBase ^, Windows::UI::Xaml::Controls::DragItemsCompletedEventArgs ^>(this, &TreeView::TreeView_DragItemsCompleted);
|
|
||||||
ItemsSource = flatViewModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeView::TreeView_OnItemClick(Platform::Object^ sender, Windows::UI::Xaml::Controls::ItemClickEventArgs^ args)
|
|
||||||
{
|
|
||||||
TreeViewItemClickEventArgs^ treeViewArgs = ref new TreeViewItemClickEventArgs();
|
|
||||||
treeViewArgs->ClickedItem = args->ClickedItem;
|
|
||||||
|
|
||||||
TreeViewItemClick(this, treeViewArgs);
|
|
||||||
|
|
||||||
if (!treeViewArgs->IsHandled)
|
|
||||||
{
|
|
||||||
TreeNode^ targetNode = (TreeNode^)args->ClickedItem;
|
|
||||||
if (targetNode->IsExpanded)
|
|
||||||
{
|
|
||||||
flatViewModel->CollapseNode(targetNode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
flatViewModel->ExpandNode(targetNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeView::TreeView_DragItemsStarting(Platform::Object^ sender, Windows::UI::Xaml::Controls::DragItemsStartingEventArgs^ e)
|
|
||||||
{
|
|
||||||
draggedTreeViewItem = (TreeViewItem^)this->ContainerFromItem(e->Items->GetAt(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeView::TreeView_DragItemsCompleted(Windows::UI::Xaml::Controls::ListViewBase^ sender, Windows::UI::Xaml::Controls::DragItemsCompletedEventArgs^ args)
|
|
||||||
{
|
|
||||||
draggedTreeViewItem = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeView::OnDrop(Windows::UI::Xaml::DragEventArgs^ e)
|
|
||||||
{
|
|
||||||
if (e->AcceptedOperation == Windows::ApplicationModel::DataTransfer::DataPackageOperation::Move)
|
|
||||||
{
|
|
||||||
Panel^ panel = this->ItemsPanelRoot;
|
|
||||||
Windows::Foundation::Point point = e->GetPosition(panel);
|
|
||||||
|
|
||||||
int aboveIndex = -1;
|
|
||||||
int belowIndex = -1;
|
|
||||||
unsigned int relativeIndex;
|
|
||||||
|
|
||||||
IInsertionPanel^ insertionPanel = (IInsertionPanel^)panel;
|
|
||||||
|
|
||||||
if (insertionPanel != nullptr)
|
|
||||||
{
|
|
||||||
insertionPanel->GetInsertionIndexes(point, &aboveIndex, &belowIndex);
|
|
||||||
|
|
||||||
TreeNode^ aboveNode = (TreeNode^)flatViewModel->GetAt(aboveIndex);
|
|
||||||
TreeNode^ belowNode = (TreeNode^)flatViewModel->GetAt(belowIndex);
|
|
||||||
TreeNode^ targetNode = (TreeNode^)this->ItemFromContainer(draggedTreeViewItem);
|
|
||||||
|
|
||||||
//Between two items
|
|
||||||
if (aboveNode && belowNode)
|
|
||||||
{
|
|
||||||
targetNode->ParentNode->IndexOf(targetNode, &relativeIndex);
|
|
||||||
targetNode->ParentNode->RemoveAt(relativeIndex);
|
|
||||||
|
|
||||||
if (belowNode->ParentNode == aboveNode)
|
|
||||||
{
|
|
||||||
aboveNode->InsertAt(0, targetNode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
aboveNode->ParentNode->IndexOf(aboveNode, &relativeIndex);
|
|
||||||
aboveNode->ParentNode->InsertAt(relativeIndex + 1, targetNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Bottom of the list
|
|
||||||
else if (aboveNode && !belowNode)
|
|
||||||
{
|
|
||||||
targetNode->ParentNode->IndexOf(targetNode, &relativeIndex);
|
|
||||||
targetNode->ParentNode->RemoveAt(relativeIndex);
|
|
||||||
|
|
||||||
aboveNode->ParentNode->IndexOf(aboveNode, &relativeIndex);
|
|
||||||
aboveNode->ParentNode->InsertAt(relativeIndex + 1, targetNode);
|
|
||||||
}
|
|
||||||
//Top of the list
|
|
||||||
else if (!aboveNode && belowNode)
|
|
||||||
{
|
|
||||||
targetNode->ParentNode->IndexOf(targetNode, &relativeIndex);
|
|
||||||
targetNode->ParentNode->RemoveAt(relativeIndex);
|
|
||||||
|
|
||||||
rootNode->InsertAt(0, targetNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
e->Handled = true;
|
|
||||||
ListViewBase::OnDrop(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeView::OnDragOver(Windows::UI::Xaml::DragEventArgs^ e)
|
|
||||||
{
|
|
||||||
Windows::ApplicationModel::DataTransfer::DataPackageOperation savedOperation = Windows::ApplicationModel::DataTransfer::DataPackageOperation::None;
|
|
||||||
|
|
||||||
e->AcceptedOperation = Windows::ApplicationModel::DataTransfer::DataPackageOperation::None;
|
|
||||||
|
|
||||||
Panel^ panel = this->ItemsPanelRoot;
|
|
||||||
Windows::Foundation::Point point = e->GetPosition(panel);
|
|
||||||
|
|
||||||
int aboveIndex = -1;
|
|
||||||
int belowIndex = -1;
|
|
||||||
|
|
||||||
IInsertionPanel^ insertionPanel = (IInsertionPanel^)panel;
|
|
||||||
|
|
||||||
if (insertionPanel != nullptr)
|
|
||||||
{
|
|
||||||
insertionPanel->GetInsertionIndexes(point, &aboveIndex, &belowIndex);
|
|
||||||
|
|
||||||
if (aboveIndex > -1)
|
|
||||||
{
|
|
||||||
TreeNode^ aboveNode = (TreeNode^)flatViewModel->GetAt(aboveIndex);
|
|
||||||
TreeNode^ targetNode = (TreeNode^)this->ItemFromContainer(draggedTreeViewItem);
|
|
||||||
|
|
||||||
TreeNode^ ancestorNode = aboveNode;
|
|
||||||
while (ancestorNode != nullptr && ancestorNode != targetNode)
|
|
||||||
{
|
|
||||||
ancestorNode = ancestorNode->ParentNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ancestorNode == nullptr)
|
|
||||||
{
|
|
||||||
savedOperation = Windows::ApplicationModel::DataTransfer::DataPackageOperation::Move;
|
|
||||||
e->AcceptedOperation = Windows::ApplicationModel::DataTransfer::DataPackageOperation::Move;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
savedOperation = Windows::ApplicationModel::DataTransfer::DataPackageOperation::Move;
|
|
||||||
e->AcceptedOperation = Windows::ApplicationModel::DataTransfer::DataPackageOperation::Move;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ListViewBase::OnDragOver(e);
|
|
||||||
e->AcceptedOperation = savedOperation;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeView::ExpandNode(TreeNode^ targetNode)
|
|
||||||
{
|
|
||||||
flatViewModel->ExpandNode(targetNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeView::CollapseNode(TreeNode^ targetNode)
|
|
||||||
{
|
|
||||||
flatViewModel->CollapseNode(targetNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeView::PrepareContainerForItemOverride(DependencyObject^ element, Object^ item)
|
|
||||||
{
|
|
||||||
((UIElement^)element)->AllowDrop = true;
|
|
||||||
|
|
||||||
ListView::PrepareContainerForItemOverride(element, item);
|
|
||||||
}
|
|
||||||
|
|
||||||
DependencyObject^ TreeView::GetContainerForItemOverride()
|
|
||||||
{
|
|
||||||
TreeViewItem^ targetItem = ref new TreeViewItem();
|
|
||||||
return (DependencyObject^)targetItem;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,75 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "TreeNode.h"
|
|
||||||
#include "ViewModel.h"
|
|
||||||
#include "TreeViewItem.h"
|
|
||||||
|
|
||||||
namespace TreeViewControl {
|
|
||||||
public ref class TreeViewItemClickEventArgs sealed
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TreeViewItemClickEventArgs() {}
|
|
||||||
|
|
||||||
property Object^ ClickedItem
|
|
||||||
{
|
|
||||||
Object^ get() { return clickedItem; };
|
|
||||||
void set(Object^ value) { clickedItem = value; };
|
|
||||||
}
|
|
||||||
|
|
||||||
property bool IsHandled
|
|
||||||
{
|
|
||||||
bool get() { return isHandled; };
|
|
||||||
void set(bool value) { isHandled = value; };
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
Object^ clickedItem = nullptr;
|
|
||||||
bool isHandled = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
ref class TreeView;
|
|
||||||
[Windows::Foundation::Metadata::WebHostHidden]
|
|
||||||
public delegate void TreeViewItemClickHandler(TreeView^ sender, TreeViewItemClickEventArgs^ args);
|
|
||||||
|
|
||||||
[Windows::Foundation::Metadata::WebHostHidden]
|
|
||||||
public ref class TreeView sealed : Windows::UI::Xaml::Controls::ListView
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TreeView();
|
|
||||||
|
|
||||||
//This event is used to expose an alternative to itemclick to developers.
|
|
||||||
event TreeViewItemClickHandler^ TreeViewItemClick;
|
|
||||||
|
|
||||||
//This RootNode property is used by the TreeView to handle additions into the TreeView and
|
|
||||||
//accurate VectorChange with multiple 'root level nodes'. This node will not be placed
|
|
||||||
//in the flatViewModel, but has it's vectorchanged event hooked up to flatViewModel's
|
|
||||||
//handler.
|
|
||||||
property TreeNode^ RootNode
|
|
||||||
{
|
|
||||||
TreeNode^ get() { return rootNode; };
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeView_OnItemClick(Platform::Object^ sender, Windows::UI::Xaml::Controls::ItemClickEventArgs^ args);
|
|
||||||
|
|
||||||
void TreeView_DragItemsStarting(Platform::Object^ sender, Windows::UI::Xaml::Controls::DragItemsStartingEventArgs^ e);
|
|
||||||
|
|
||||||
void TreeView_DragItemsCompleted(Windows::UI::Xaml::Controls::ListViewBase^ sender, Windows::UI::Xaml::Controls::DragItemsCompletedEventArgs^ args);
|
|
||||||
|
|
||||||
void ExpandNode(TreeNode^ targetNode);
|
|
||||||
|
|
||||||
void CollapseNode(TreeNode^ targetNode);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void PrepareContainerForItemOverride(DependencyObject^ element, Object^ item) override;
|
|
||||||
Windows::UI::Xaml::DependencyObject^ GetContainerForItemOverride() override;
|
|
||||||
|
|
||||||
void OnDrop(Windows::UI::Xaml::DragEventArgs^ e) override;
|
|
||||||
void OnDragOver(Windows::UI::Xaml::DragEventArgs^ e) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
TreeNode^ rootNode;
|
|
||||||
ViewModel^ flatViewModel;
|
|
||||||
|
|
||||||
internal:
|
|
||||||
TreeViewItem^ draggedTreeViewItem;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,237 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|ARM">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>ARM</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Debug|x64">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>x64</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|ARM">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>ARM</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|x64">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>x64</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>{bdc228d2-7929-5a98-b7ba-5e28bd1adbcf}</ProjectGuid>
|
|
||||||
<Keyword>WindowsRuntimeComponent</Keyword>
|
|
||||||
<ProjectName>TreeViewControl</ProjectName>
|
|
||||||
<RootNamespace>TreeViewControl</RootNamespace>
|
|
||||||
<DefaultLanguage>en-US</DefaultLanguage>
|
|
||||||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
|
||||||
<AppContainerApplication>true</AppContainerApplication>
|
|
||||||
<ApplicationType>Windows Store</ApplicationType>
|
|
||||||
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
|
|
||||||
<WindowsTargetPlatformMinVersion>10.0.17134.0</WindowsTargetPlatformMinVersion>
|
|
||||||
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
|
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
|
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="Shared">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<GenerateManifest>false</GenerateManifest>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<GenerateManifest>false</GenerateManifest>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
|
||||||
<GenerateManifest>false</GenerateManifest>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
|
||||||
<GenerateManifest>false</GenerateManifest>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<GenerateManifest>false</GenerateManifest>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<GenerateManifest>false</GenerateManifest>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
||||||
<PreprocessorDefinitions>_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
|
||||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
|
||||||
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
|
||||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
<DisableSpecificWarnings>28204</DisableSpecificWarnings>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
||||||
<PreprocessorDefinitions>_WINRT_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
|
||||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
|
||||||
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
|
||||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
<DisableSpecificWarnings>28204</DisableSpecificWarnings>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
||||||
<PreprocessorDefinitions>_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
|
||||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
|
||||||
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
|
||||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
<DisableSpecificWarnings>28204</DisableSpecificWarnings>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
||||||
<PreprocessorDefinitions>_WINRT_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
|
||||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
|
||||||
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
|
||||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
<DisableSpecificWarnings>28204</DisableSpecificWarnings>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
||||||
<PreprocessorDefinitions>_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
|
||||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
|
||||||
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
|
||||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
<DisableSpecificWarnings>28204</DisableSpecificWarnings>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
||||||
<PreprocessorDefinitions>_WINRT_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
|
||||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
|
||||||
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
|
||||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
|
||||||
<DisableSpecificWarnings>28204</DisableSpecificWarnings>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="IntegerToIndentationConverter.h" />
|
|
||||||
<ClInclude Include="pch.h" />
|
|
||||||
<ClInclude Include="TreeNode.h" />
|
|
||||||
<ClInclude Include="TreeView.h" />
|
|
||||||
<ClInclude Include="TreeViewItem.h" />
|
|
||||||
<ClInclude Include="TreeViewItemAutomationPeer.h" />
|
|
||||||
<ClInclude Include="ViewModel.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="IntegerToIndentationConverter.cpp" />
|
|
||||||
<ClCompile Include="pch.cpp">
|
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Create</PrecompiledHeader>
|
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Create</PrecompiledHeader>
|
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="TreeNode.cpp" />
|
|
||||||
<ClCompile Include="TreeView.cpp" />
|
|
||||||
<ClCompile Include="TreeViewItem.cpp" />
|
|
||||||
<ClCompile Include="TreeViewItemAutomationPeer.cpp" />
|
|
||||||
<ClCompile Include="ViewModel.cpp" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
|
@ -1,27 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup>
|
|
||||||
<Filter Include="Resources">
|
|
||||||
<UniqueIdentifier>96c875b2-800f-42e2-aba6-ef897e02ec12</UniqueIdentifier>
|
|
||||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
|
||||||
</Filter>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="pch.cpp" />
|
|
||||||
<ClCompile Include="TreeNode.cpp" />
|
|
||||||
<ClCompile Include="TreeView.cpp" />
|
|
||||||
<ClCompile Include="TreeViewItem.cpp" />
|
|
||||||
<ClCompile Include="TreeViewItemAutomationPeer.cpp" />
|
|
||||||
<ClCompile Include="ViewModel.cpp" />
|
|
||||||
<ClCompile Include="IntegerToIndentationConverter.cpp" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="pch.h" />
|
|
||||||
<ClInclude Include="TreeNode.h" />
|
|
||||||
<ClInclude Include="TreeView.h" />
|
|
||||||
<ClInclude Include="TreeViewItem.h" />
|
|
||||||
<ClInclude Include="TreeViewItemAutomationPeer.h" />
|
|
||||||
<ClInclude Include="ViewModel.h" />
|
|
||||||
<ClInclude Include="IntegerToIndentationConverter.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
|
@ -1,127 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "pch.h"
|
|
||||||
#include "TreeViewItem.h"
|
|
||||||
#include "TreeViewItemAutomationPeer.h"
|
|
||||||
|
|
||||||
using namespace Windows::UI::Xaml;
|
|
||||||
using namespace Platform;
|
|
||||||
|
|
||||||
namespace TreeViewControl {
|
|
||||||
TreeViewItem::TreeViewItem()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
TreeViewItem::~TreeViewItem()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Windows::UI::Xaml::Controls::ListView^ TreeViewItem::GetAncestorListView(TreeViewItem^ targetItem)
|
|
||||||
{
|
|
||||||
DependencyObject^ TreeViewItemAncestor = (DependencyObject^)this;
|
|
||||||
Windows::UI::Xaml::Controls::ListView^ ancestorListView = nullptr;
|
|
||||||
while (TreeViewItemAncestor != nullptr && ancestorListView == nullptr)
|
|
||||||
{
|
|
||||||
TreeViewItemAncestor = Windows::UI::Xaml::Media::VisualTreeHelper::GetParent(TreeViewItemAncestor);
|
|
||||||
ancestorListView = dynamic_cast<Windows::UI::Xaml::Controls::ListView^>(TreeViewItemAncestor);
|
|
||||||
}
|
|
||||||
return ancestorListView;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeViewItem::OnDrop(Windows::UI::Xaml::DragEventArgs^ e)
|
|
||||||
{
|
|
||||||
if (e->AcceptedOperation == Windows::ApplicationModel::DataTransfer::DataPackageOperation::Move)
|
|
||||||
{
|
|
||||||
TreeViewItem^ droppedOnItem = (TreeViewItem^)this;
|
|
||||||
|
|
||||||
Windows::UI::Xaml::Controls::ListView^ ancestorListView = GetAncestorListView(droppedOnItem);
|
|
||||||
|
|
||||||
if (ancestorListView)
|
|
||||||
{
|
|
||||||
TreeView^ ancestorTreeView = (TreeView^)ancestorListView;
|
|
||||||
TreeViewItem^ droppedItem = ancestorTreeView->draggedTreeViewItem;
|
|
||||||
TreeNode^ droppedNode = (TreeNode^)ancestorTreeView->ItemFromContainer(droppedItem);
|
|
||||||
TreeNode^ droppedOnNode = (TreeNode^)ancestorTreeView->ItemFromContainer(droppedOnItem);
|
|
||||||
|
|
||||||
//Remove the item that was dragged
|
|
||||||
unsigned int removeIndex;
|
|
||||||
droppedNode->ParentNode->IndexOf(droppedNode, &removeIndex);
|
|
||||||
|
|
||||||
if (droppedNode != droppedOnNode)
|
|
||||||
{
|
|
||||||
droppedNode->ParentNode->RemoveAt(removeIndex);
|
|
||||||
|
|
||||||
//Append the dragged dropped item as a child of the node it was dropped onto
|
|
||||||
droppedOnNode->Append(droppedNode);
|
|
||||||
|
|
||||||
//If not set to true then the Reorder code of listview wil override what is being done here.
|
|
||||||
e->Handled = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
e->AcceptedOperation = Windows::ApplicationModel::DataTransfer::DataPackageOperation::None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeViewItem::OnDragEnter(Windows::UI::Xaml::DragEventArgs^ e)
|
|
||||||
{
|
|
||||||
TreeViewItem^ draggedOverItem = (TreeViewItem^)this;
|
|
||||||
|
|
||||||
e->AcceptedOperation = Windows::ApplicationModel::DataTransfer::DataPackageOperation::None;
|
|
||||||
|
|
||||||
Windows::UI::Xaml::Controls::ListView^ ancestorListView = GetAncestorListView(draggedOverItem);
|
|
||||||
|
|
||||||
if (ancestorListView)
|
|
||||||
{
|
|
||||||
TreeView^ ancestorTreeView = (TreeView^)ancestorListView;
|
|
||||||
TreeViewItem^ draggedTreeViewItem = ancestorTreeView->draggedTreeViewItem;
|
|
||||||
TreeNode^ draggedNode = (TreeNode^)ancestorTreeView->ItemFromContainer(draggedTreeViewItem);
|
|
||||||
TreeNode^ draggedOverNode = (TreeNode^)ancestorTreeView->ItemFromContainer(draggedOverItem);
|
|
||||||
TreeNode^ walkNode = draggedOverNode->ParentNode;
|
|
||||||
|
|
||||||
while (walkNode != nullptr && walkNode != draggedNode)
|
|
||||||
{
|
|
||||||
walkNode = walkNode->ParentNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (walkNode != draggedNode && draggedNode != draggedOverNode)
|
|
||||||
{
|
|
||||||
e->AcceptedOperation = Windows::ApplicationModel::DataTransfer::DataPackageOperation::Move;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeViewItem::OnDragOver(Windows::UI::Xaml::DragEventArgs^ e)
|
|
||||||
{
|
|
||||||
e->DragUIOverride->IsGlyphVisible = true;
|
|
||||||
e->AcceptedOperation = Windows::ApplicationModel::DataTransfer::DataPackageOperation::None;
|
|
||||||
|
|
||||||
TreeViewItem^ draggedOverItem = (TreeViewItem^)this;
|
|
||||||
|
|
||||||
Windows::UI::Xaml::Controls::ListView^ ancestorListView = GetAncestorListView(draggedOverItem);
|
|
||||||
if (ancestorListView)
|
|
||||||
{
|
|
||||||
TreeView^ ancestorTreeView = (TreeView^)ancestorListView;
|
|
||||||
TreeViewItem^ draggedTreeViewItem = ancestorTreeView->draggedTreeViewItem;
|
|
||||||
TreeNode^ draggedNode = (TreeNode^)ancestorTreeView->ItemFromContainer(draggedTreeViewItem);
|
|
||||||
TreeNode^ draggedOverNode = (TreeNode^)ancestorTreeView->ItemFromContainer(draggedOverItem);
|
|
||||||
TreeNode^ walkNode = draggedOverNode->ParentNode;
|
|
||||||
|
|
||||||
while (walkNode != nullptr && walkNode != draggedNode)
|
|
||||||
{
|
|
||||||
walkNode = walkNode->ParentNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (walkNode != draggedNode && draggedNode != draggedOverNode)
|
|
||||||
{
|
|
||||||
e->AcceptedOperation = Windows::ApplicationModel::DataTransfer::DataPackageOperation::Move;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Windows::UI::Xaml::Automation::Peers::AutomationPeer^ TreeViewItem::OnCreateAutomationPeer()
|
|
||||||
{
|
|
||||||
return ref new TreeViewItemAutomationPeer(this);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace TreeViewControl {
|
|
||||||
[Windows::Foundation::Metadata::WebHostHidden]
|
|
||||||
[Windows::UI::Xaml::Data::Bindable]
|
|
||||||
public ref class TreeViewItem sealed : Windows::UI::Xaml::Controls::ListViewItem
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TreeViewItem();
|
|
||||||
|
|
||||||
virtual ~TreeViewItem();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Windows::UI::Xaml::Controls::ListView^ GetAncestorListView(TreeViewItem^ targetItem);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void OnDrop(Windows::UI::Xaml::DragEventArgs^ e) override;
|
|
||||||
void OnDragEnter(Windows::UI::Xaml::DragEventArgs^ e) override;
|
|
||||||
void OnDragOver(Windows::UI::Xaml::DragEventArgs^ e) override;
|
|
||||||
Windows::UI::Xaml::Automation::Peers::AutomationPeer^ OnCreateAutomationPeer() override;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,178 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "pch.h"
|
|
||||||
#include "TreeViewItemAutomationPeer.h"
|
|
||||||
#include "TreeNode.h"
|
|
||||||
|
|
||||||
using namespace Windows::UI::Xaml;
|
|
||||||
using namespace Windows::UI::Xaml::Automation;
|
|
||||||
using namespace Windows::UI::Xaml::Controls;
|
|
||||||
using namespace Windows::UI::Xaml::Data;
|
|
||||||
|
|
||||||
|
|
||||||
namespace TreeViewControl {
|
|
||||||
//IExpandCollapseProvider
|
|
||||||
Windows::UI::Xaml::Automation::ExpandCollapseState TreeViewItemAutomationPeer::ExpandCollapseState::get()
|
|
||||||
{
|
|
||||||
Windows::UI::Xaml::Automation::ExpandCollapseState currentState = Windows::UI::Xaml::Automation::ExpandCollapseState::Collapsed;
|
|
||||||
Windows::UI::Xaml::Controls::ListView^ ancestorListView = GetParentListView((DependencyObject^)Owner);
|
|
||||||
|
|
||||||
TreeNode^ targetNode;
|
|
||||||
TreeNode^ targetParentNode;
|
|
||||||
|
|
||||||
if (ancestorListView)
|
|
||||||
{
|
|
||||||
TreeView^ ancestorTreeView = (TreeView^)ancestorListView;
|
|
||||||
targetNode = (TreeNode^)ancestorTreeView->ItemFromContainer((TreeViewItem^)Owner);
|
|
||||||
|
|
||||||
if (Owner->AllowDrop)
|
|
||||||
{
|
|
||||||
if (targetNode->IsExpanded)
|
|
||||||
{
|
|
||||||
currentState = Windows::UI::Xaml::Automation::ExpandCollapseState::Expanded;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
currentState = Windows::UI::Xaml::Automation::ExpandCollapseState::Collapsed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
currentState = Windows::UI::Xaml::Automation::ExpandCollapseState::LeafNode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return currentState;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeViewItemAutomationPeer::Collapse()
|
|
||||||
{
|
|
||||||
Windows::UI::Xaml::Controls::ListView^ ancestorListView = GetParentListView((DependencyObject^)Owner);
|
|
||||||
|
|
||||||
if (ancestorListView)
|
|
||||||
{
|
|
||||||
TreeView^ ancestorTreeView = (TreeView^)ancestorListView;
|
|
||||||
TreeNode^ targetNode = (TreeNode^)ancestorTreeView->ItemFromContainer((TreeViewItem^)Owner);
|
|
||||||
ancestorTreeView->CollapseNode(targetNode);
|
|
||||||
RaiseExpandCollapseAutomationEvent(Windows::UI::Xaml::Automation::ExpandCollapseState::Collapsed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeViewItemAutomationPeer::Expand()
|
|
||||||
{
|
|
||||||
Windows::UI::Xaml::Controls::ListView^ ancestorListView = GetParentListView((DependencyObject^)Owner);
|
|
||||||
|
|
||||||
if (ancestorListView)
|
|
||||||
{
|
|
||||||
TreeView^ ancestorTreeView = (TreeView^)ancestorListView;
|
|
||||||
TreeNode^ targetNode = (TreeNode^)ancestorTreeView->ItemFromContainer((TreeViewItem^)Owner);
|
|
||||||
ancestorTreeView->ExpandNode(targetNode);
|
|
||||||
RaiseExpandCollapseAutomationEvent(Windows::UI::Xaml::Automation::ExpandCollapseState::Expanded);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeViewItemAutomationPeer::RaiseExpandCollapseAutomationEvent(Windows::UI::Xaml::Automation::ExpandCollapseState newState)
|
|
||||||
{
|
|
||||||
Windows::UI::Xaml::Automation::ExpandCollapseState oldState;
|
|
||||||
|
|
||||||
if (newState == Windows::UI::Xaml::Automation::ExpandCollapseState::Expanded)
|
|
||||||
{
|
|
||||||
oldState = Windows::UI::Xaml::Automation::ExpandCollapseState::Collapsed;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
oldState = Windows::UI::Xaml::Automation::ExpandCollapseState::Expanded;
|
|
||||||
}
|
|
||||||
|
|
||||||
RaisePropertyChangedEvent(ExpandCollapsePatternIdentifiers::ExpandCollapseStateProperty, oldState, newState);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Position override
|
|
||||||
|
|
||||||
//These methods are being overridden so that the TreeView under narrator reads out
|
|
||||||
//the position of an item as compared to it's children, not it's overall position
|
|
||||||
//in the listview. I've included an override for level as well, to give context on
|
|
||||||
//how deep in the tree an item is.
|
|
||||||
int TreeViewItemAutomationPeer::GetSizeOfSetCore()
|
|
||||||
{
|
|
||||||
Windows::UI::Xaml::Controls::ListView^ ancestorListView = GetParentListView((DependencyObject^)Owner);
|
|
||||||
|
|
||||||
TreeNode^ targetNode;
|
|
||||||
TreeNode^ targetParentNode;
|
|
||||||
|
|
||||||
int setSize = 0;
|
|
||||||
|
|
||||||
if (ancestorListView)
|
|
||||||
{
|
|
||||||
TreeView^ ancestorTreeView = (TreeView^)ancestorListView;
|
|
||||||
targetNode = (TreeNode^)ancestorTreeView->ItemFromContainer((TreeViewItem^)Owner);
|
|
||||||
targetParentNode = targetNode->ParentNode;
|
|
||||||
setSize = targetParentNode->Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return setSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
int TreeViewItemAutomationPeer::GetPositionInSetCore()
|
|
||||||
{
|
|
||||||
Windows::UI::Xaml::Controls::ListView^ ancestorListView = GetParentListView((DependencyObject^)Owner);
|
|
||||||
|
|
||||||
TreeNode^ targetNode;
|
|
||||||
TreeNode^ targetParentNode;
|
|
||||||
|
|
||||||
int positionInSet = 0;
|
|
||||||
|
|
||||||
if (ancestorListView)
|
|
||||||
{
|
|
||||||
TreeView^ ancestorTreeView = (TreeView^)ancestorListView;
|
|
||||||
targetNode = (TreeNode^)ancestorTreeView->ItemFromContainer((TreeViewItem^)Owner);
|
|
||||||
unsigned int positionInt;
|
|
||||||
targetParentNode = targetNode->ParentNode;
|
|
||||||
targetParentNode->IndexOf(targetNode, &positionInt);
|
|
||||||
positionInSet = (int)positionInt + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return positionInSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
int TreeViewItemAutomationPeer::GetLevelCore()
|
|
||||||
{
|
|
||||||
Windows::UI::Xaml::Controls::ListView^ ancestorListView = GetParentListView((DependencyObject^)Owner);
|
|
||||||
|
|
||||||
TreeNode^ targetNode;
|
|
||||||
TreeNode^ targetParentNode;
|
|
||||||
|
|
||||||
int levelValue = 0;
|
|
||||||
|
|
||||||
if (ancestorListView)
|
|
||||||
{
|
|
||||||
TreeView^ ancestorTreeView = (TreeView^)ancestorListView;
|
|
||||||
targetNode = (TreeNode^)ancestorTreeView->ItemFromContainer((TreeViewItem^)Owner);
|
|
||||||
levelValue = targetNode->Depth + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return levelValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Platform::Object^ TreeViewItemAutomationPeer::GetPatternCore(Windows::UI::Xaml::Automation::Peers::PatternInterface patternInterface)
|
|
||||||
{
|
|
||||||
if (patternInterface == Windows::UI::Xaml::Automation::Peers::PatternInterface::ExpandCollapse)
|
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ListViewItemAutomationPeer::GetPatternCore(patternInterface);
|
|
||||||
}
|
|
||||||
|
|
||||||
Windows::UI::Xaml::Controls::ListView^ TreeViewItemAutomationPeer::GetParentListView(DependencyObject^ Owner)
|
|
||||||
{
|
|
||||||
DependencyObject^ treeViewItemAncestor = Owner;
|
|
||||||
Windows::UI::Xaml::Controls::ListView^ ancestorListView = nullptr;
|
|
||||||
while (treeViewItemAncestor != nullptr && ancestorListView == nullptr)
|
|
||||||
{
|
|
||||||
treeViewItemAncestor = Windows::UI::Xaml::Media::VisualTreeHelper::GetParent(treeViewItemAncestor);
|
|
||||||
ancestorListView = dynamic_cast<Windows::UI::Xaml::Controls::ListView^>(treeViewItemAncestor);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ancestorListView;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "TreeViewItem.h"
|
|
||||||
#include "TreeView.h"
|
|
||||||
|
|
||||||
namespace TreeViewControl {
|
|
||||||
[Windows::Foundation::Metadata::WebHostHidden]
|
|
||||||
public ref class TreeViewItemAutomationPeer : Windows::UI::Xaml::Automation::Peers::ListViewItemAutomationPeer, Windows::UI::Xaml::Automation::Provider::IExpandCollapseProvider
|
|
||||||
{
|
|
||||||
internal:
|
|
||||||
TreeViewItemAutomationPeer(TreeViewItem^ owner) :Windows::UI::Xaml::Automation::Peers::ListViewItemAutomationPeer(owner) {};
|
|
||||||
|
|
||||||
public:
|
|
||||||
//IExpandCollapseProvider
|
|
||||||
virtual void Collapse();
|
|
||||||
|
|
||||||
virtual void Expand();
|
|
||||||
|
|
||||||
property Windows::UI::Xaml::Automation::ExpandCollapseState ExpandCollapseState
|
|
||||||
{
|
|
||||||
virtual Windows::UI::Xaml::Automation::ExpandCollapseState get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RaiseExpandCollapseAutomationEvent(Windows::UI::Xaml::Automation::ExpandCollapseState newState);
|
|
||||||
|
|
||||||
//Position override
|
|
||||||
int GetSizeOfSetCore() override;
|
|
||||||
|
|
||||||
int GetPositionInSetCore() override;
|
|
||||||
|
|
||||||
int GetLevelCore() override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Platform::Object^ GetPatternCore(Windows::UI::Xaml::Automation::Peers::PatternInterface patternInterface) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Windows::UI::Xaml::Controls::ListView^ GetParentListView(DependencyObject^ Owner);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,450 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "pch.h"
|
|
||||||
#include "ViewModel.h"
|
|
||||||
|
|
||||||
using namespace Platform;
|
|
||||||
using namespace Windows::Foundation::Collections;
|
|
||||||
using namespace Windows::UI::Xaml::Interop;
|
|
||||||
using namespace Windows::UI::Xaml::Data;
|
|
||||||
|
|
||||||
namespace TreeViewControl {
|
|
||||||
ViewModel::ViewModel()
|
|
||||||
{
|
|
||||||
flatVectorRealizedItems->VectorChanged += ref new VectorChangedEventHandler<TreeNode ^>(this, &ViewModel::UpdateTreeView);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewModel::Append(Object^ value)
|
|
||||||
{
|
|
||||||
TreeNode^ targetNode = (TreeNode^)value;
|
|
||||||
flatVectorRealizedItems->Append(targetNode);
|
|
||||||
|
|
||||||
collectionChangedEventTokenVector.push_back(targetNode->VectorChanged += ref new BindableVectorChangedEventHandler(this, &ViewModel::TreeNodeVectorChanged));
|
|
||||||
propertyChangedEventTokenVector.push_back(targetNode->PropertyChanged += ref new Windows::UI::Xaml::Data::PropertyChangedEventHandler(this, &ViewModel::TreeNodePropertyChanged));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewModel::Clear()
|
|
||||||
{
|
|
||||||
|
|
||||||
while (flatVectorRealizedItems->Size != 0)
|
|
||||||
{
|
|
||||||
RemoveAtEnd();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IBindableIterator^ ViewModel::First()
|
|
||||||
{
|
|
||||||
return dynamic_cast<IBindableIterator^>(flatVectorRealizedItems->First());
|
|
||||||
}
|
|
||||||
|
|
||||||
Object^ ViewModel::GetAt(unsigned int index)
|
|
||||||
{
|
|
||||||
if ((int)index > -1 && (int)index < flatVectorRealizedItems->Size)
|
|
||||||
{
|
|
||||||
return flatVectorRealizedItems->GetAt(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
IBindableVectorView^ ViewModel::GetView()
|
|
||||||
{
|
|
||||||
return safe_cast<IBindableVectorView^>(flatVectorRealizedItems->GetView());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ViewModel::IndexOf(Object^ value, unsigned int* index)
|
|
||||||
{
|
|
||||||
return flatVectorRealizedItems->IndexOf((TreeNode^)value, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewModel::InsertAt(unsigned int index, Object^ value)
|
|
||||||
{
|
|
||||||
if ((int)index > -1 && (int)index <= flatVectorRealizedItems->Size)
|
|
||||||
{
|
|
||||||
TreeNode^ targetNode = (TreeNode^)value;
|
|
||||||
flatVectorRealizedItems->InsertAt(index, targetNode);
|
|
||||||
|
|
||||||
auto eventIndex = collectionChangedEventTokenVector.begin() + index;
|
|
||||||
collectionChangedEventTokenVector.insert(eventIndex, targetNode->VectorChanged += ref new BindableVectorChangedEventHandler(this, &ViewModel::TreeNodeVectorChanged));
|
|
||||||
|
|
||||||
eventIndex = propertyChangedEventTokenVector.begin() + index;
|
|
||||||
propertyChangedEventTokenVector.insert(eventIndex,targetNode->PropertyChanged += ref new Windows::UI::Xaml::Data::PropertyChangedEventHandler(this, &ViewModel::TreeNodePropertyChanged));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewModel::RemoveAt(unsigned int index)
|
|
||||||
{
|
|
||||||
if ((int)index > -1 && (int)index < flatVectorRealizedItems->Size)
|
|
||||||
{
|
|
||||||
TreeNode^ targetNode = flatVectorRealizedItems->GetAt(index);
|
|
||||||
flatVectorRealizedItems->RemoveAt(index);
|
|
||||||
|
|
||||||
auto eventIndex = collectionChangedEventTokenVector.begin() + index;
|
|
||||||
targetNode->VectorChanged -= collectionChangedEventTokenVector[index];
|
|
||||||
collectionChangedEventTokenVector.erase(eventIndex);
|
|
||||||
|
|
||||||
eventIndex = propertyChangedEventTokenVector.begin() + index;
|
|
||||||
targetNode->PropertyChanged -= propertyChangedEventTokenVector[index];
|
|
||||||
propertyChangedEventTokenVector.erase(eventIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewModel::RemoveAtEnd()
|
|
||||||
{
|
|
||||||
int index = flatVectorRealizedItems->Size - 1;
|
|
||||||
if (index >= 0)
|
|
||||||
{
|
|
||||||
TreeNode^ targetNode = flatVectorRealizedItems->GetAt(index);
|
|
||||||
flatVectorRealizedItems->RemoveAt(index);
|
|
||||||
|
|
||||||
auto eventIndex = collectionChangedEventTokenVector.begin() + index;
|
|
||||||
targetNode->VectorChanged -= collectionChangedEventTokenVector[index];
|
|
||||||
collectionChangedEventTokenVector.erase(eventIndex);
|
|
||||||
|
|
||||||
eventIndex = propertyChangedEventTokenVector.begin() + index;
|
|
||||||
targetNode->PropertyChanged -= propertyChangedEventTokenVector[index];
|
|
||||||
propertyChangedEventTokenVector.erase(eventIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewModel::SetAt(unsigned int index, Object^ value)
|
|
||||||
{
|
|
||||||
if ((int)index > -1 && (int)index < flatVectorRealizedItems->Size)
|
|
||||||
{
|
|
||||||
TreeNode^ targetNode = (TreeNode^)value;
|
|
||||||
TreeNode^ removeNode = flatVectorRealizedItems->GetAt(index);
|
|
||||||
flatVectorRealizedItems->SetAt(index, targetNode);
|
|
||||||
|
|
||||||
auto eventIndex = collectionChangedEventTokenVector.begin() + index;
|
|
||||||
removeNode->VectorChanged -= collectionChangedEventTokenVector[index];
|
|
||||||
collectionChangedEventTokenVector.erase(eventIndex);
|
|
||||||
collectionChangedEventTokenVector.insert(eventIndex, targetNode->VectorChanged += ref new BindableVectorChangedEventHandler(this, &ViewModel::TreeNodeVectorChanged));
|
|
||||||
|
|
||||||
eventIndex = propertyChangedEventTokenVector.begin() + index;
|
|
||||||
targetNode->PropertyChanged -= propertyChangedEventTokenVector[index];
|
|
||||||
propertyChangedEventTokenVector.erase(eventIndex);
|
|
||||||
propertyChangedEventTokenVector.insert(eventIndex, targetNode->PropertyChanged += ref new Windows::UI::Xaml::Data::PropertyChangedEventHandler(this, &ViewModel::TreeNodePropertyChanged));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewModel::ExpandNode(TreeNode^ targetNode)
|
|
||||||
{
|
|
||||||
if (!targetNode->IsExpanded)
|
|
||||||
{
|
|
||||||
targetNode->IsExpanded = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewModel::CollapseNode(TreeNode^ targetNode)
|
|
||||||
{
|
|
||||||
if (targetNode->IsExpanded)
|
|
||||||
{
|
|
||||||
targetNode->IsExpanded = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewModel::AddNodeToView(TreeNode^ targetNode, int index)
|
|
||||||
{
|
|
||||||
InsertAt(index, targetNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ViewModel::AddNodeDescendantsToView(TreeNode^ targetNode, int index, int offset)
|
|
||||||
{
|
|
||||||
if (targetNode->IsExpanded)
|
|
||||||
{
|
|
||||||
TreeNode^ childNode;
|
|
||||||
for (int i = 0; i < (int)targetNode->Size; i++)
|
|
||||||
{
|
|
||||||
childNode = (TreeNode^)targetNode->GetAt(i);
|
|
||||||
offset++;
|
|
||||||
AddNodeToView(childNode, index + offset);
|
|
||||||
offset = AddNodeDescendantsToView(childNode, index, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewModel::RemoveNodeAndDescendantsFromView(TreeNode^ targetNode)
|
|
||||||
{
|
|
||||||
if (targetNode->IsExpanded)
|
|
||||||
{
|
|
||||||
TreeNode^ childNode;
|
|
||||||
for (int i = 0; i < (int)targetNode->Size; i++)
|
|
||||||
{
|
|
||||||
childNode = (TreeNode^)targetNode->GetAt(i);
|
|
||||||
RemoveNodeAndDescendantsFromView(childNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int index = IndexOf(targetNode);
|
|
||||||
RemoveAt(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ViewModel::CountDescendants(TreeNode^ targetNode)
|
|
||||||
{
|
|
||||||
int descendantCount = 0;
|
|
||||||
TreeNode^ childNode;
|
|
||||||
for (int i = 0; i < (int)targetNode->Size; i++)
|
|
||||||
{
|
|
||||||
childNode = (TreeNode^)targetNode->GetAt(i);
|
|
||||||
descendantCount++;
|
|
||||||
if (childNode->IsExpanded)
|
|
||||||
{
|
|
||||||
descendantCount = descendantCount + CountDescendants(childNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return descendantCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ViewModel::IndexOf(TreeNode^ targetNode)
|
|
||||||
{
|
|
||||||
unsigned int index;
|
|
||||||
bool isIndexed = IndexOf(targetNode, &index);
|
|
||||||
if (isIndexed)
|
|
||||||
{
|
|
||||||
return (int)index;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewModel::UpdateTreeView(IObservableVector<TreeNode^>^ sender, IVectorChangedEventArgs^ e)
|
|
||||||
{
|
|
||||||
VectorChanged(this, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewModel::TreeNodeVectorChanged(IBindableObservableVector^ sender, Platform::Object^ e)
|
|
||||||
{
|
|
||||||
CollectionChange CC = ((IVectorChangedEventArgs^)e)->CollectionChange;
|
|
||||||
switch (CC)
|
|
||||||
{
|
|
||||||
//Reset case, commonly seen when a TreeNode is cleared.
|
|
||||||
//removes all nodes that need removing then
|
|
||||||
//toggles a collapse / expand to ensure order.
|
|
||||||
case (CollectionChange::Reset) :
|
|
||||||
{
|
|
||||||
TreeNode^ resetNode = (TreeNode^)sender;
|
|
||||||
int resetIndex = IndexOf(resetNode);
|
|
||||||
if (resetIndex != Size - 1 && resetNode->IsExpanded)
|
|
||||||
{
|
|
||||||
TreeNode^ childNode = resetNode;
|
|
||||||
TreeNode^ parentNode = resetNode->ParentNode;
|
|
||||||
int stopIndex;
|
|
||||||
bool isLastRelativeChild = true;
|
|
||||||
while (parentNode != nullptr && isLastRelativeChild)
|
|
||||||
{
|
|
||||||
unsigned int relativeIndex;
|
|
||||||
parentNode->IndexOf(childNode, &relativeIndex);
|
|
||||||
if (parentNode->Size - 1 != relativeIndex)
|
|
||||||
{
|
|
||||||
isLastRelativeChild = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
childNode = parentNode;
|
|
||||||
parentNode = parentNode->ParentNode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parentNode != nullptr)
|
|
||||||
{
|
|
||||||
unsigned int siblingIndex;
|
|
||||||
parentNode->IndexOf(childNode, &siblingIndex);
|
|
||||||
TreeNode^ siblingNode = (TreeNode^)parentNode->GetAt(siblingIndex + 1);
|
|
||||||
stopIndex = IndexOf(siblingNode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stopIndex = Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = stopIndex - 1; i > resetIndex; i--)
|
|
||||||
{
|
|
||||||
if ((flatVectorRealizedItems->GetAt(i))->ParentNode == nullptr)
|
|
||||||
{
|
|
||||||
RemoveNodeAndDescendantsFromView(flatVectorRealizedItems->GetAt(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resetNode->IsExpanded)
|
|
||||||
{
|
|
||||||
CollapseNode(resetNode);
|
|
||||||
ExpandNode(resetNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Inserts the TreeNode into the correct index of the ViewModel
|
|
||||||
case (CollectionChange::ItemInserted) :
|
|
||||||
{
|
|
||||||
//We will find the correct index of insertion by first checking if the
|
|
||||||
//node we are inserting into is expanded. If it is we will start walking
|
|
||||||
//down the tree and counting the open items. This is to ensure we place
|
|
||||||
//the inserted item in the correct index. If along the way we bump into
|
|
||||||
//the item being inserted, we insert there then return, because we don't
|
|
||||||
//need to do anything further.
|
|
||||||
unsigned int index = ((IVectorChangedEventArgs^)e)->Index;
|
|
||||||
TreeNode^ targetNode = (TreeNode^)sender->GetAt(index);
|
|
||||||
TreeNode^ parentNode = targetNode->ParentNode;
|
|
||||||
TreeNode^ childNode;
|
|
||||||
int parentIndex = IndexOf(parentNode);
|
|
||||||
int allOpenedDescendantsCount = 0;
|
|
||||||
if (parentNode->IsExpanded)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < (int)parentNode->Size; i++)
|
|
||||||
{
|
|
||||||
childNode = (TreeNode^)parentNode->GetAt(i);
|
|
||||||
if (childNode == targetNode)
|
|
||||||
{
|
|
||||||
AddNodeToView(targetNode, (parentIndex + i + 1 + allOpenedDescendantsCount));
|
|
||||||
if (targetNode->IsExpanded)
|
|
||||||
{
|
|
||||||
AddNodeDescendantsToView(targetNode, parentIndex + i + 1, allOpenedDescendantsCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (childNode->IsExpanded)
|
|
||||||
{
|
|
||||||
allOpenedDescendantsCount += CountDescendants(childNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AddNodeToView(targetNode, (parentIndex + parentNode->Size + allOpenedDescendantsCount));
|
|
||||||
if (targetNode->IsExpanded)
|
|
||||||
{
|
|
||||||
AddNodeDescendantsToView(targetNode, parentIndex + parentNode->Size, allOpenedDescendantsCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Removes a node from the ViewModel when a TreeNode
|
|
||||||
//removes a child.
|
|
||||||
case (CollectionChange::ItemRemoved) :
|
|
||||||
{
|
|
||||||
TreeNode^ removeNode = (TreeNode^)sender;
|
|
||||||
int removeIndex = IndexOf(removeNode);
|
|
||||||
|
|
||||||
if (removeIndex != Size - 1 && removeNode->IsExpanded)
|
|
||||||
{
|
|
||||||
TreeNode^ childNode = removeNode;
|
|
||||||
TreeNode^ parentNode = removeNode->ParentNode;
|
|
||||||
int stopIndex;
|
|
||||||
bool isLastRelativeChild = true;
|
|
||||||
while (parentNode != nullptr && isLastRelativeChild)
|
|
||||||
{
|
|
||||||
unsigned int relativeIndex;
|
|
||||||
parentNode->IndexOf(childNode, &relativeIndex);
|
|
||||||
if (parentNode->Size - 1 != relativeIndex)
|
|
||||||
{
|
|
||||||
isLastRelativeChild = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
childNode = parentNode;
|
|
||||||
parentNode = parentNode->ParentNode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parentNode != nullptr)
|
|
||||||
{
|
|
||||||
unsigned int siblingIndex;
|
|
||||||
parentNode->IndexOf(childNode, &siblingIndex);
|
|
||||||
TreeNode^ siblingNode = (TreeNode^)parentNode->GetAt(siblingIndex + 1);
|
|
||||||
stopIndex = IndexOf(siblingNode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stopIndex = Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = stopIndex - 1; i > removeIndex; i--)
|
|
||||||
{
|
|
||||||
if ((flatVectorRealizedItems->GetAt(i))->ParentNode == nullptr)
|
|
||||||
{
|
|
||||||
RemoveNodeAndDescendantsFromView(flatVectorRealizedItems->GetAt(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Triggered by a replace such as SetAt.
|
|
||||||
//Updates the TreeNode that changed in the ViewModel.
|
|
||||||
case (CollectionChange::ItemChanged) :
|
|
||||||
{
|
|
||||||
unsigned int index = ((IVectorChangedEventArgs^)e)->Index;
|
|
||||||
TreeNode^ targetNode = (TreeNode^)sender->GetAt(index);
|
|
||||||
TreeNode^ parentNode = targetNode->ParentNode;
|
|
||||||
TreeNode^ childNode;
|
|
||||||
int allOpenedDescendantsCount = 0;
|
|
||||||
int parentIndex = IndexOf(parentNode);
|
|
||||||
|
|
||||||
for (int i = 0; i < (int)parentNode->Size; i++)
|
|
||||||
{
|
|
||||||
childNode = (TreeNode^)parentNode->GetAt(i);
|
|
||||||
if (childNode->IsExpanded)
|
|
||||||
{
|
|
||||||
allOpenedDescendantsCount += CountDescendants(childNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TreeNode^ removeNode = (TreeNode^)GetAt(parentIndex + index + allOpenedDescendantsCount + 1);
|
|
||||||
if (removeNode->IsExpanded)
|
|
||||||
{
|
|
||||||
CollapseNode(removeNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveAt(parentIndex + index + allOpenedDescendantsCount + 1);
|
|
||||||
InsertAt(parentIndex + index + allOpenedDescendantsCount + 1, targetNode);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewModel::TreeNodePropertyChanged(Object^ sender, PropertyChangedEventArgs^ e)
|
|
||||||
{
|
|
||||||
if (e->PropertyName == "IsExpanded")
|
|
||||||
{
|
|
||||||
TreeNode^ targetNode = (TreeNode^)sender;
|
|
||||||
if (targetNode->IsExpanded)
|
|
||||||
{
|
|
||||||
if (targetNode->Size != 0)
|
|
||||||
{
|
|
||||||
int openedDescendantOffset = 0;
|
|
||||||
int index = IndexOf(targetNode);
|
|
||||||
index = index + 1;
|
|
||||||
TreeNode^ childNode;
|
|
||||||
for (int i = 0; i < (int)targetNode->Size; i++)
|
|
||||||
{
|
|
||||||
childNode = (TreeNode^)targetNode->GetAt(i);
|
|
||||||
AddNodeToView(childNode, ((int)index + i + openedDescendantOffset));
|
|
||||||
openedDescendantOffset = AddNodeDescendantsToView(childNode, (index + i), openedDescendantOffset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TreeNode^ childNode;
|
|
||||||
for (int i = 0; i < (int)targetNode->Size; i++)
|
|
||||||
{
|
|
||||||
childNode = (TreeNode^)targetNode->GetAt(i);
|
|
||||||
RemoveNodeAndDescendantsFromView(childNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,105 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "TreeNode.h"
|
|
||||||
|
|
||||||
namespace TreeViewControl {
|
|
||||||
/// <summary>
|
|
||||||
/// The ViewModel is responsible for flattening the heirarchical data into a flat list.
|
|
||||||
/// It also tracks changes to the underlying data and updates the flat list accordingly.
|
|
||||||
/// </summary>
|
|
||||||
[Windows::Foundation::Metadata::WebHostHidden]
|
|
||||||
ref class ViewModel sealed : Windows::UI::Xaml::Interop::IBindableObservableVector
|
|
||||||
{
|
|
||||||
internal:
|
|
||||||
ViewModel();
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// <summary>
|
|
||||||
/// Add root to the view model. In other cases the app should not
|
|
||||||
/// use this api.
|
|
||||||
/// </summary>
|
|
||||||
virtual void Append(Object^ value);
|
|
||||||
|
|
||||||
virtual void Clear();
|
|
||||||
|
|
||||||
virtual Windows::UI::Xaml::Interop::IBindableIterator^ First();
|
|
||||||
|
|
||||||
virtual Object^ GetAt(unsigned int index);
|
|
||||||
|
|
||||||
virtual Windows::UI::Xaml::Interop::IBindableVectorView^ GetView();
|
|
||||||
|
|
||||||
virtual bool IndexOf(Object^ value, unsigned int* index);
|
|
||||||
|
|
||||||
virtual void InsertAt(unsigned int index, Object^ value);
|
|
||||||
|
|
||||||
virtual void RemoveAt(unsigned int index);
|
|
||||||
|
|
||||||
virtual void RemoveAtEnd();
|
|
||||||
|
|
||||||
virtual void SetAt(unsigned int index, Object^ value);
|
|
||||||
|
|
||||||
virtual property unsigned int Size
|
|
||||||
{
|
|
||||||
unsigned int get() { return flatVectorRealizedItems->Size; };
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual event Windows::UI::Xaml::Interop::BindableVectorChangedEventHandler^ VectorChanged
|
|
||||||
{
|
|
||||||
virtual Windows::Foundation::EventRegistrationToken add(Windows::UI::Xaml::Interop::BindableVectorChangedEventHandler^ args)
|
|
||||||
{
|
|
||||||
return ViewModelChanged += args;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void remove(Windows::Foundation::EventRegistrationToken token)
|
|
||||||
{
|
|
||||||
return ViewModelChanged -= token;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void raise(Windows::UI::Xaml::Interop::IBindableObservableVector^ vector, Platform::Object^ e)
|
|
||||||
{
|
|
||||||
ViewModelChanged(vector, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ExpandNode adds the children and all open descendants of the targetNode
|
|
||||||
/// to the ViewModel in their correct flattened index.
|
|
||||||
/// </summary>
|
|
||||||
void ExpandNode(TreeNode^ targetNode);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Collapse node removes all the descendants of the targetNode from the ViewModel.
|
|
||||||
/// </summary>
|
|
||||||
void CollapseNode(TreeNode^ targetNode);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This is the collection changed handler for individual TreeNodes. The collection changes
|
|
||||||
/// from the hierarchical TreeNodes need to be flattened so that we can keep our current
|
|
||||||
/// flat list in sync.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender">TreeNode that has already been changed</param>
|
|
||||||
void TreeNodeVectorChanged(Windows::UI::Xaml::Interop::IBindableObservableVector^ sender, Platform::Object^ e);
|
|
||||||
|
|
||||||
void TreeNodePropertyChanged(Object^ sender, Windows::UI::Xaml::Data::PropertyChangedEventArgs^ e);
|
|
||||||
|
|
||||||
private:
|
|
||||||
event Windows::UI::Xaml::Interop::BindableVectorChangedEventHandler^ ViewModelChanged;
|
|
||||||
|
|
||||||
Platform::Collections::Vector<TreeNode^>^ flatVectorRealizedItems = ref new Platform::Collections::Vector<TreeNode^>();
|
|
||||||
|
|
||||||
std::vector<Windows::Foundation::EventRegistrationToken> collectionChangedEventTokenVector;
|
|
||||||
|
|
||||||
std::vector<Windows::Foundation::EventRegistrationToken> propertyChangedEventTokenVector;
|
|
||||||
|
|
||||||
void AddNodeToView(TreeNode^ targetNode, int index);
|
|
||||||
|
|
||||||
int AddNodeDescendantsToView(TreeNode^ targetNode, int start, int offset);
|
|
||||||
|
|
||||||
void RemoveNodeAndDescendantsFromView(TreeNode^ targetNode);
|
|
||||||
|
|
||||||
int CountDescendants(TreeNode^ targetNode);
|
|
||||||
|
|
||||||
int IndexOf(TreeNode^ targetNode);
|
|
||||||
|
|
||||||
void UpdateTreeView(Windows::Foundation::Collections::IObservableVector<TreeNode^>^ sender, Windows::Foundation::Collections::IVectorChangedEventArgs^ e);
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
#include "pch.h"
|
|
|
@ -1,10 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <collection.h>
|
|
||||||
#include <ppltasks.h>
|
|
||||||
#include <TreeNode.h>
|
|
||||||
#include <ViewModel.h>
|
|
||||||
#include <TreeViewItem.h>
|
|
||||||
#include <TreeView.h>
|
|
||||||
#include <TreeViewItemAutomationPeer.h>
|
|
||||||
#include <IntegerToIndentationConverter.h>
|
|
|
@ -414,9 +414,6 @@
|
||||||
</Page>
|
</Page>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Control\TreeViewControl.vcxproj">
|
|
||||||
<Project>{bdc228d2-7929-5a98-b7ba-5e28bd1adbcf}</Project>
|
|
||||||
</ProjectReference>
|
|
||||||
<ProjectReference Include="..\WinRTGLTFParser\WinRTGLTFParser.vcxproj">
|
<ProjectReference Include="..\WinRTGLTFParser\WinRTGLTFParser.vcxproj">
|
||||||
<Project>{31117527-af30-485c-a312-846bc6a25e0b}</Project>
|
<Project>{31117527-af30-485c-a312-846bc6a25e0b}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
|
|
@ -13,8 +13,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SharedGLTFParser", "SharedG
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ModelViewer", "ModelViewer\ModelViewer.vcxproj", "{28B2A92C-D6ED-4A02-9448-B554BF5A95DC}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ModelViewer", "ModelViewer\ModelViewer.vcxproj", "{28B2A92C-D6ED-4A02-9448-B554BF5A95DC}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TreeViewControl", "Control\TreeViewControl.vcxproj", "{BDC228D2-7929-5A98-B7BA-5E28BD1ADBCF}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||||
SharedGLTFParser\SharedGLTFParser.vcxitems*{31117527-af30-485c-a312-846bc6a25e0b}*SharedItemsImports = 4
|
SharedGLTFParser\SharedGLTFParser.vcxitems*{31117527-af30-485c-a312-846bc6a25e0b}*SharedItemsImports = 4
|
||||||
|
@ -80,18 +78,6 @@ Global
|
||||||
{28B2A92C-D6ED-4A02-9448-B554BF5A95DC}.Release|x86.ActiveCfg = Release|Win32
|
{28B2A92C-D6ED-4A02-9448-B554BF5A95DC}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{28B2A92C-D6ED-4A02-9448-B554BF5A95DC}.Release|x86.Build.0 = Release|Win32
|
{28B2A92C-D6ED-4A02-9448-B554BF5A95DC}.Release|x86.Build.0 = Release|Win32
|
||||||
{28B2A92C-D6ED-4A02-9448-B554BF5A95DC}.Release|x86.Deploy.0 = Release|Win32
|
{28B2A92C-D6ED-4A02-9448-B554BF5A95DC}.Release|x86.Deploy.0 = Release|Win32
|
||||||
{BDC228D2-7929-5A98-B7BA-5E28BD1ADBCF}.Debug|ARM.ActiveCfg = Debug|ARM
|
|
||||||
{BDC228D2-7929-5A98-B7BA-5E28BD1ADBCF}.Debug|ARM.Build.0 = Debug|ARM
|
|
||||||
{BDC228D2-7929-5A98-B7BA-5E28BD1ADBCF}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{BDC228D2-7929-5A98-B7BA-5E28BD1ADBCF}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{BDC228D2-7929-5A98-B7BA-5E28BD1ADBCF}.Debug|x86.ActiveCfg = Debug|Win32
|
|
||||||
{BDC228D2-7929-5A98-B7BA-5E28BD1ADBCF}.Debug|x86.Build.0 = Debug|Win32
|
|
||||||
{BDC228D2-7929-5A98-B7BA-5E28BD1ADBCF}.Release|ARM.ActiveCfg = Release|ARM
|
|
||||||
{BDC228D2-7929-5A98-B7BA-5E28BD1ADBCF}.Release|ARM.Build.0 = Release|ARM
|
|
||||||
{BDC228D2-7929-5A98-B7BA-5E28BD1ADBCF}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{BDC228D2-7929-5A98-B7BA-5E28BD1ADBCF}.Release|x64.Build.0 = Release|x64
|
|
||||||
{BDC228D2-7929-5A98-B7BA-5E28BD1ADBCF}.Release|x86.ActiveCfg = Release|Win32
|
|
||||||
{BDC228D2-7929-5A98-B7BA-5E28BD1ADBCF}.Release|x86.Build.0 = Release|Win32
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
Загрузка…
Ссылка в новой задаче