I was trying to create a treeview browser for my application but got stuck somewhere.
The treeview isn't getting displayed.
Code:
System::IO::DirectoryInfo^ info = gcnew System::IO::DirectoryInfo(path);
System::IO::Directory^ dir;
if (dir->Exists(path))
{
try
{
array<System::IO::DirectoryInfo^>^ dirs = info->GetDirectories();
if (dirs->Length > 0)
{
for (int i = 0; i < dirs->Length; i++)
{
TreeNode^ node = treeView1->Nodes[0]->Nodes->Add(dirs[i]->Name);
node->ImageIndex = 1;
for (int j = 0; j < dirs[i]->GetFiles()->Length; j++)
{
if (dirs[i]->GetFiles()[j]->Exists)
{
TreeNode^ nodes = treeView1->Nodes[0]->Nodes[node->Index]->Nodes->Add(dirs[i]->GetFiles()[j]->Name);
nodes->ImageIndex = 2;
}
}
}
}
}
catch (Exception^ e)
{
MessageBox::Show(e->Message);
}
}
Did you use splitcontainer and fill in the first section with your data first?
How did you initialize the new treeview class?
Example:
[ComVisibleAttribute(true)]
[ClassInterfaceAttribute(ClassInterfaceType::AutoDispatch)]
[DockingAttribute(DockingBehavior::Ask)]
public ref class TreeView : public Control
Then you can implement treeview and imageview.
For example, ShGetFolderLocation is one way to pull file locations, for windows OS.
Remember you have to populate the view and tell the system to display it for you to see it.
Or just go to: this earlier solution for the same issue
Follow up with the code for nodemouse click or whatever input response you are looking for such as expand or close, go to link and so on.
Related
I am working on android using Xamarin and MVVMCross framework. I want to update the remove the fragment from fragment manager to handle the back button, Because i have to navigate between screen which make a cross reference in Back Stack. So i want to remove the repetitive entries from stack. Its removing the repetitive entries from stack but it does not update the BackStackEntryCount with latest fragments.
I have written code
public override void OnFragmentChanged(IMvxCachedFragmentInfo fragmentInfo)
{
if (fragmentInfo != null)
{
var ifExists =
SupportFragmentManager.Fragments?.FirstOrDefault(x => x.Tag.ToLower() == fragmentInfo.Tag.ToLower());
if (ifExists != null)
{
var indexOf = SupportFragmentManager.Fragments.IndexOf(ifExists);
var total = SupportFragmentManager.BackStackEntryCount;
for (int i = indexOf + 1; i < total; i++)
{
SupportFragmentManager.Fragments.RemoveAt(i);
}
}
}
base.OnFragmentChanged(fragmentInfo);
}
SupportFragmentManager.Fragments is a read only property (It only has a get). Modifying the content of the list of fragment has no impact on the underline fragment backstack count.
What you can instead try is to pop the stack down to the existing fragment. This should remove all fragments above it.
var exisitngFragment = SupportFragmentManager.FindFragmentByTag(fragmentInfo.Tag);
SupportFragmentManager.PopBackStackImmediate(exisitngFragment.Id, 0);
I read in this article http://www.adobe.com/devnet/flex/articles/flex-mobile-performance-checklist.html that I should not initialize a View's appearance in a creationComplete handler. Instead, I should change view's appearance in an overridden data setter.
The section in the article is:
Override the data setter instead of using bindings or initializing a View's appearance in a creationComplete handler
1-First, I would like to know if I got this right by doing the following:
//My code is loading a set of images and adding them in a View.
//On creationComplete of the View I am adding the images in case this is the first time
//the view is shown. In case the view has been already accessed I use the data:
protected function view1_creationCompleteHandler(event:FlexEvent):void
{
if(!data) //On first creation of the view I create the data object
{
data = new Object();
data.imageArray = new Array(); //set an array that will cache my images.
for(var i:int = 0; i<36;i++)
{
var img:Image = new Image();
img.source = 'assets/0'+i.toString()+'.png';
container.addElement(img);
(data.imageArray as Array).push(img);//Override the data for next time!
}
}
else//Next time use the save images
{
for(var ix:int = 0; ix<(data.imageArray as Array).length;ix++)
{
container.addElement((data.imageArray as Array)[ix]);
}
}
}
If I am doing this correctly, I would like to know which approach is best. The above one, or the next one I am going to show which uses the images contentLoader with caching and queuing enabled with a ContentCache:
protected function view1_creationCompleteHandler(event:FlexEvent):void
{
{
for(var i:int = 0; i<36;i++)
{
var img:Image = new Image();
img.contentLoader = ldr;
img.contentLoaderGrouping = 'gr1';
img.source = 'assets/0'+i.toString()+'.png';
container.addElement(img);
}
}
<fx:Declarations>
<s:ContentCache id="ldr" enableQueueing="true"
maxActiveRequests="1" maxCacheEntries="36"/>
</fx:Declarations>
Also if someone could tell me what is the contentLoaderGrouping for. I would be very grateful.
Thanks a lot!!!
PS:By the way both approaches work. The first approach is instant while the second approach shows the images beeing added in a very smooth way which actually gives a cool effect.
Neither. The point of the suggestion was to NOT alter the displaylist after creationComplete, which requires an additional update cycle. Instead you should inject the data property when you push your view on the stack, and initiate your changes in the setter. Using the ContentCache has nothing to do with it (and can sometimes cause additional overhead if not used correctly).
override public function set data(value:Object):void
{
super.data = value;
//this was poorly optimized, so I made it
//a little better...
var imageArray:Array = (value == null || value.imageArray == null)?
null : value.imageArray as Array;
if(imageArray == null) //On first creation of the view I create the data object
{
imageArray = new Array(36); //set an array that will cache my images.
for(var i:int = 0; i<36;i++)
{
var img:Image = new Image();
img.source = 'assets/0'+i.toString()+'.png';
container.addElement(img);
imageArray[i] = img;
}
super.data = {imageArray:imageArray}
}
else//Next time use the save images
{
var n:int = imageArray.length;
for (var j:int = 0; j < n; j++)
{
container.addElement(IVisualElement(imageArray[j]));
}
}
}
EDIT
I was mistaken about when the data property is set during the view life-cycle.
Here is how it works:
So you are correct that container would be null at that point. I was going to write up an example for you, but I'm having trouble figuring out what your end goal is here. Is there a specific reason you are storing the images on the data property? I think what you might actually want to do is this:
private var _data:Object = {cache: new ContentCache()};
protected function show_clickHandler(event:MouseEvent):void
{
this.navigator.pushView(views.MyView, _data);
}
And in the view...
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" title="MyView">
<fx:Script>
<![CDATA[
import spark.components.Image;
import spark.core.ContentCache;
override protected function createChildren():void
{
super.createChildren();
//you might want to do a sanity first check to make sure the
//data was passed in correctly...
var cache:ContentCache = ContentCache(this.data.cache);
for(var i:int = 0; i < 36; i++)
{
var img:Image = new Image();
img.contentLoader = cache;
img.source = 'assets/0' + i.toString() + '.png';
container.addElement(img);
}
}
]]>
</fx:Script>
<s:VGroup id="container" />
</s:View>
The ITHit Ajax Browser function right-click “Update file…” our users consider very dangerous. For example it is possible to update a .doc file with a .xls file resulting in a "corrupt" word file which in fact contains Excel workbook so we have been removing this menu item in ITHitAJAXFileBrowser.js file at each new Ajax Browser release. Will it be possible to improve or remove the feature by customization?
Thanks
To remove the menu item in Ajax File Browser you can use the following code:
ITHit.Events.AddListener(ajaxFileBrowser.GetMenuManager(), 'OnShowMenu', onShowMenu);
...
function onShowMenu(menu, aContextMenuHierarchyItems) {
var index = getMenuIndexByMenuId(menu, 'CustomProperties');
if (index != -1) {
menu.Children.splice(index, 1);
}
}
function getMenuIndexByMenuId(menu, menuId) {
for (var i = 0, l = menu.Children.length; i < l; i++) {
if (menu.Children[i].Id == menuId) {
return i;
}
}
return -1;
}
Please find more info here:
http://www.webdavsystem.com/ajaxfilebrowser/programming/context_menu_customization
http://www.ajaxbrowser.com/?menudlgdemo
I'm looking for a simple way to loop through all buttons onscreen for a given tag. Eg "foo". I'm using WP7, using C#. I'm very new to the platform so go easy on me :P
Googling this sort of thing isn't really working out for me either - I think I have my terminology wrong, so any tips on that too would be appreciated.
You should probably loop through all the controls on your page, check whether each one is a button, and if so check its Tag property.
Something like this...
foreach (UIElement ctrl in ContentPanel.Children)
{
if (ctrl.GetType() == typeof(Button))
{
Button potentialButton = ((Button)ctrl);
if (potentialButton.Tag = Tag)
return (Button)ctrl;
}
}
Bear in mind, though, that if you have nested controls on the page, you will need to think about recursing into any item with children to make sure you catch all the controls.
First, create a method to enumerate recursively the controls in your page:
public static IEnumerable<FrameworkElement> FindVisualChildren(FrameworkElement control)
{
if (control == null)
{
yield break;
}
for (int i = 0; i < System.Windows.Media.VisualTreeHelper.GetChildrenCount(control); i++)
{
var child = System.Windows.Media.VisualTreeHelper.GetChild(control, i) as FrameworkElement;
if (child != null)
{
yield return child;
foreach (var grandChild in FindVisualChildren(child))
{
yield return grandChild;
}
}
}
}
Then call it and keep only the controls you want:
var buttons = FindVisualChildren(this.ContentPanel)
.OfType<Button>()
.Where(b => b.Tag is string && (string)b.Tag == "foo");
(where ContentPanel is the root element of your page)
i have a a Pivot that has a ListBox defined as its Pivot.ItemTemplate as the following.
<controls:Pivot x:Name="pivot">
<controls:Pivot.ItemTemplate>
<DataTemplate>
<ListBox x:Name="listBox">
...
</ListBox>
</DataTemplate>
</controls:Pivot.ItemTemplate>
</controls:Pivot>
how do i programmatically access the corresponding ListBox control corresponding to the Pivot.SelectedItem or Pivot.SelectedIndex?
i tried something similar to this link http://www.windowsphonegeek.com/tips/how-to-access-a-control-placed-inside-listbox-itemtemplate-in-wp7.
var count = VisualTreeHelper.GetChildrenCount(pivotItem);
for(int i=0; i < count; i++) {
var child = VisualTreeHelper.GetChild(pivotItem, i);
if(child is ListBox) {
//do something
} else {
Debug.WriteLine(child.GetType());
}
}
for some reason, i get System.Windows.Controls.Grid on the Debug.WriteLine.
the reason why i need to get a handle or access the ListBox inside the Pivot (that is currently on display/selected), is because i need to reset its view (scroll it back to the top). the ListBox is data bound to ObservableCollection, and when i update the collection, the scroll position needs to be placed back to the top; otherwise, everything works (data binding/visual display), except now the view is stuck in the middle or where the user currently is. if there's an easier way to do this without getting a handle on the ListBox, i'm open to that solution as well.
just in case anyone is interested, i tinkered and came up with something that works specifically for my case. the code is below. basically, i had to get the PivotItem first.
PivotItem pivotItem = pivot.ItemContainerGenerator.ContainerFromItem(myObject) as PivotItem;
i then created a local variable to store the ListBox (if it's found) and recursed the tree view model.
ListBox listBox = null;
Recurse(pivotItem, ref listBox);
and my Recurse function looks like the following.
private void Recurse(DependencyObject obj, ref ListBox listBox) {
if(obj is ListBox) {
listBox = obj as ListBox;
return;
}
var count = VisualTreeHelper.GetChildrenCount(obj);
for(int i=0; i < count; i++) {
var child = VisualTreeHelper.GetChild(obj, i);
Recurse(child, ref listBox);
}
}
try:
(Listbox)VisualTreeHelper.GetChild((pivot.SelectedItem as PivotItem), 0);
Looks like this was a while back, but this is what worked for me:
First get the PivotItem:
PivotItem pivotItem = Pivot.ItemContainerGenerator.ContainerFromItem(Pivot.SelectedItem) as PivotItem;
Then get the first child, a ListBox, from the PivotItem:
private T FindFirstElementInVisualTree<T>(DependencyObject parentElement) where T : DependencyObject {
var count = VisualTreeHelper.GetChildrenCount(parentElement);
if (count == 0)
return null;
for (int i = 0; i < count; i++) {
var child = VisualTreeHelper.GetChild(parentElement, i);
if (child != null && child is T) {
return (T)child;
} else {
var result = FindFirstElementInVisualTree<T>(child);
if (result != null)
return result;
}
}
return null;
}
Then call:
ListBox listBox = FindFirstElementInVisualTree<ListBox>(pivotItem);
use StackPanel inside your ListBox
this link may help you
http://blogs.msdn.com/b/oren/archive/2010/11/08/wp7-silverlight-perf-demo-1-virtualizingstackpanel-vs-stackpanel-as-a-listbox-itemspanel.aspx