I need to update textblock inside childWindow based on file name that is being selected with OpenDialog Window. Since I am not running OpenDialog from childWindow I have trouble passing that value to the texblock inside ChildWindow. I am wondering if someone can help. As a result of th issue I have, I am wondering if it is possible to have OpenDialog inside ChildWindow? Thank you for any ideas!
ChildWindow xaml:
<sdk:ChildWindow
x:Class="AddPackages_ChildWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
AutomationProperties.AutomationId="AddPackages_ChildWindow">
<Grid x:Name="AddPackages_ChildWindow_LayoutRoot" AutomationProperties.AutomationId="AddPackages_ChildWindow_LayoutRoot" Style="{StaticResource AVV_GridStyle}">
<TextBlock x:Name="txtUpdate_Package" AutomationProperties.AutomationId="txtUpdate_Package" Text="FileName" /> </Grid>
Below is the code to open DialogBox and passing selected file name:
private void Package_Click(object sender, System.Windows.RoutedEventArgs e)
{
AddPackage_ChildWindow ap = new AddPackage_ChildWindow();
ap.Show();
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "App-V Packages (*.sprj)|*.sprj|App-V Packages (*.sprj)|*.sprj";
openFileDialog1.FilterIndex = 1;
openFileDialog1.Multiselect = true;
bool? userClickedOK = openFileDialog1.ShowDialog();
if (userClickedOK == true)
{
//passing the file name string
txtUpdate_Package.Text = openFileDialog1.File.Name;
System.IO.Stream fileStream = openFileDialog1.File.OpenRead();
using (System.IO.StreamReader reader = new System.IO.StreamReader(fileStream))
{
// Read the first line from the file and write it the textbox.
// txtUpdate_Package.Text = reader.ReadLine();
}
fileStream.Close();
}
}
You could expose a SetText method on your ChildWindow class like so:
public void SetText(string text) {
this.txtUpdate_Package.Text = text;
}
Then you'd call it like so from your Package_Click method:
ap.SetText(reader.ReadLine());
If you're not too concerned with what the the OO purists think you can change this line in your code:-
txtUpdate_Package.Text = openFileDialog1.File.Name;
to this:-
ap.txtUpdate_Package.Text = openFileDialog1.File.Name;
This works because the auto-generated class file created for your child window Xaml will have a field of type TextBlock called txtUpdate_Package with the access of internal, i.e.
internal TextBlock txUpdate_Package;
This field is is assigned during the ChildWindow's InitializeComponent method called as part of its constructor.
However, I would prefer to create a public property to be used to handle this rather than write code the relies on what should be considered the private internal structure. Add this property to the Code behind of your child window.
public string Text
{
get { return txtUpdate_Package.Text; }
set { txtUpdate_Package.Text = value; }
}
Related
Problem
A user WPF control is made up of multiple standard controls.
How can multiple dependency properties of the component (base or standard) controls be accessed in XAML, when implementing the parent (user) control, without creating additional properties?
Details
What do I mean by "creating additional dependency properties"? Well, that is the only way I know of accessing properties of the component controls: by implementing attached properties, as described at MSDN here.
However, it presents the following problems:
Existing dependency properties must be copied as new properties, defeating the DRY principle.
If data binding is to occur, more work must be done to bind existing dependency properties to the new exposed dependency properties.
I'm wondering if there is a way to "walk" the base controls within the user control, to access their properties - from within XAML.
Example
For example, I make a user WPF control that inherits from UserControl. It is simple - it consists of a StackPanel containing a Label and a TextBlock:
<UserControl x:Class="MyApp.CustomControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<Label Name="BaseLabel">Label Here</Label>
<TextBlock Name="BaseTextBlock">Some text here.</TextBlock>
</StackPanel>
</UserControl>
Now, when I use my UserControl elsewhere in XAML, I'm wishfully thinking something like this could be done to edit my Label's content... although I don't know of a way:
<Window x:Class="MyApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyApp">
<StackPanel>
<!-- This won't work, don't try at home kids. -->
<local:CustomControl BaseLabel.Content="I did it!"></local:CustomControl>
</StackPanel>
</Window>
Much thanks.
How about the next solution:
1. Create the AttachedProperty (because you must an entry point) and bind this property to the collection of data.This collection of data will contain changes you want perform on sub-controls of a main user control used inside the window. This collection will be defined inside the main window view model.
2. In attached property changed callback get the binded collection, parse it data into sub-controls properties.
Here is the solution:
3. Xaml code:
<Window.DataContext>
<nirHelpingOvalButton:MainWindowViewModel />
</Window.DataContext>
<Grid>
<nirHelpingOvalButton:InnerControl x:Name="MyInnerControl"
nirHelpingOvalButton:Helper.InnerControlPropertiesAccessor="{Binding InnerData, Mode=Default, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
4. Attached property code (bindig support):
public static readonly DependencyProperty InnerControlPropertiesAccessorProperty = DependencyProperty.RegisterAttached(
"InnerControlPropertiesAccessor", typeof (ObservableCollection<TargetControlData>), typeof (Helper), new PropertyMetadata(default(ObservableCollection<TargetControlData>), InnerValueAccessProviderPropertyChangedCallback));
public static void SetInnerControlPropertiesAccessor(DependencyObject element, ObservableCollection<TargetControlData> value)
{
element.SetValue(InnerControlPropertiesAccessorProperty, value);
}
public static ObservableCollection<TargetControlData> GetInnerControlPropertiesAccessor(DependencyObject element)
{
return (ObservableCollection<TargetControlData>) element.GetValue(InnerControlPropertiesAccessorProperty);
}
private static void InnerValueAccessProviderPropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
var control = sender as Control;
if (control == null) return;
var valuesMap = args.NewValue as ObservableCollection<TargetControlData>;
if (valuesMap == null)
return;
valuesMap.ToList().ForEach(data => TryToBind(control, data));
}
private static void TryToBind(Control control, TargetControlData data)
{
var innerControl = control.FindName(data.SubControlName) as DependencyObject;
if (innerControl == null) return;
var myBinding = new Binding
{
Source = data,
Path = new PropertyPath("Data"),
Mode = BindingMode.TwoWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
};
var descriptors = TypeDescriptor.GetProperties(innerControl);
var propertyDescriptor = descriptors.Find(data.SubConrolProperty, true);
var descriptor = DependencyPropertyDescriptor.FromProperty(propertyDescriptor);
if (descriptor == null) return;
var dependencyProperty = descriptor.DependencyProperty;
BindingOperations.SetBinding(innerControl, dependencyProperty, myBinding);
}
5. Inner control xaml:
<UserControl x:Class="NirHelpingOvalButton.InnerControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UniformGrid>
<Button x:Name="InnerControlButton"></Button>
<TextBlock x:Name="InnerContentTextBlock"></TextBlock>
</UniformGrid>
6. ViewModel code:
public class MainWindowViewModel:BaseObservableObject
{
private static int _staticCount = 0;
private List<Brush> _list = new List<Brush> {Brushes.Green, Brushes.Red, Brushes.Blue};
public MainWindowViewModel()
{
InnerData = new ObservableCollection<TargetControlData>
{
new TargetControlData
{
SubControlName = "InnerControlButton",
SubConrolProperty = "Content",
Data = "Click Me",
},
new TargetControlData
{
SubControlName = "InnerControlButton",
SubConrolProperty = "Command",
Data = new RelayCommand(CommandMethod),
},
new TargetControlData
{
SubConrolProperty = "Text",
SubControlName = "InnerContentTextBlock",
Data = "Hello"
},
new TargetControlData
{
SubConrolProperty = "Background",
SubControlName = "InnerContentTextBlock",
Data = Brushes.Green
},
new TargetControlData
{
SubConrolProperty = "Foreground",
SubControlName = "InnerContentTextBlock",
Data = Brushes.White
},
};
}
private void CommandMethod()
{
_staticCount ++;
var backgroundData = InnerData.FirstOrDefault(data => data.SubControlName == "InnerContentTextBlock" && data.SubConrolProperty == "Background");
var textData = InnerData.FirstOrDefault(data => data.SubControlName == "InnerContentTextBlock" && data.SubConrolProperty == "Text");
if (backgroundData == null || textData == null) return;
var index = _staticCount%_list.Count;
backgroundData.Data = _list[index];
textData.Data = string.Format("{0} {1}", "Hello", backgroundData.Data);
}
public ObservableCollection<TargetControlData> InnerData { get; set; }}
7. TargetControlData code:
public class TargetControlData:BaseObservableObject
{
private string _subControlName;
private string _subConrolProperty;
private object _data;
public string SubControlName
{
get { return _subControlName; }
set
{
_subControlName = value;
OnPropertyChanged();
}
}
public string SubConrolProperty
{
get { return _subConrolProperty; }
set
{
_subConrolProperty = value;
OnPropertyChanged();
}
}
public object Data
{
get { return _data; }
set
{
_data = value;
OnPropertyChanged();
}
}
}
Summary - you can pull control properties data from configuration file, or collect them by reflection.
regards,
The way you suggested - I don't think this would be possible.
But it can be done with normal properties, instead of dependency properties, something like:
UserControl xaml:
<StackPanel>
<TextBlock x:Name="tbOne"></TextBlock>
<TextBlock x:Name="tbTwo" Foreground="Red"></TextBlock>
</StackPanel>
UserControl code behind:
public string One
{
get
{
return this.tbOne.Text;
}
set
{
this.tbOne.Text = value;
}
}
public string Two
{
get
{
return this.tbTwo.Text;
}
set
{
this.tbTwo.Text = value;
}
}
and the usage of user control:
<local:UserControl1 One="test1" Two="test2"></local:UserControl1>
I have a DataGrid which is bound to an ObservableCollection ProductsFound
which is exposed as a property in my ViewModel.
By typing text in a TextBox, products contained in the model that have the Code property that contains the text inserted in the TextBox are added to ProductsFound.
I found out that if the DataGrid is contained in any control such as a StackPanel or a TabItem, the Window (the program) stops responding when I try to type text into the TextBox; while if the DataGrid isn't contained in any control, everything runs normally.
Here's the code for the window:
public class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// This method just fill the dataset I pass to the model's contructor in the next line.
Init();
ProductsModel model = new ProductsModel(dataSet);
searchViewModel = new ProductsSearchViewModel(model);
DataContext = searchViewModel;
}
private ProductsSearchViewModel searchViewModel;
// This handler supports the binding between the TextBox and the MatchText property of the View Model.
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
var binding = ((TextBox)sender).GetBindingExpression(TextBox.TextProperty);
binding.UpdateSource();
}
}
And here's my ViewModel:
public class ProductsSearchViewModel : Notifier, IProductsSearchViewModel
{
public ProductsSearchViewModel(IProductsModel inModel)
{
model = inModel;
productsFound = new ObservableCollection<ProductViewModel>();
}
private string matchText;
private IProductsModel model;
private ObservableCollection<ProductViewModel> productsFound;
// This is a helper method that search for the products in the model and adds them to ProductsFound.
private void Search(string text)
{
Results.Clear();
foreach (Product product in model.Products)
{
if (product.Code.ToLower().Contains(text.ToLower()))
Results.Add(new ProductViewModel(product));
}
}
public string MatchText
{
get { return matchText; }
// This setter is meant to be executed every time the Text property of the TextBox is changed.
set
{
if ((value != matchText) && (value != ""))
{
matchText = value;
// This raises INotifyPropertyChanged.PropertyChaged.
NotifyPropertyChanged("MatchText");
Search(value);
}
}
}
public ObservableCollection<ProductViewModel> ProductsFound
{
get
{
return productsFound;
}
set
{
productsFound = value;
NotifyPropertyChanged("Results");
}
}
}
Here's the XAML:
<Window x:Class="MyNameSpace.UI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel>
<TextBox Text="{Binding MatchText, Mode=TwoWay}" TextChanged="TextBox_TextChanged" />
<DataGrid x:Name="grid1" ItemsSource="{Binding Results}" >
</StackPanel>
</Grid>
With that StackPanel the program stops responding when I try to type text in the Textbox and no item is added to the DataGrid; but if i remove it everything runs ok.
What could the problem be? Am I missing something in how the WPF binding system works?
Is my view model coded wrong?
Thanks in advance.
Putting that StackPanel there prevents the DataGrid from acquiring a specific Height, thus it just expands down to infinity, and that breaks UI Virtualization.
Remove the StackPanel from there and use a non-infinite container, such as Grid or DockPanel.
How can I add programmatically LayoutDocument with some of UIElements inside it? (like stackpanel, scrollviewer etc.) I'd like to add new LayoutDocument with stackpanel, canvas etc. to LayoutDocumentPane when user clicks "New project" button. May I somehow clone xaml code from one LayoutDocument and load it's to new one? And is it possible to bind Title LayoutDocument property to ViewModel Property? ( i get error it has to be dependency property )
You can use Content property. For example if you want to add a new LayoutDocument with a custom content (StackPanel e.g.) you could do it as follow:
//Get the main LayoutDocumentPane of your DockingManager
var documentPane = dockManager.Layout.Descendents().OfType<LayoutDocumentPane>().FirstOrDefault();
if (documentPane != null)
{
LayoutDocument layoutDocument = new LayoutDocument {Title = "New Document"};
//*********Here you could add whatever you want***********
layoutDocument.Content = new StackPanel();
//Add the new LayoutDocument to the existing array
documentPane.Children.Add(layoutDocument);
}
First, in XAML - give the name to the Grid, for example, x:Name = "mainGrid"
Then in class write this
//Create button - we put this in document
Button mybutton = new Button();
mybutton.Content = "hello";
mybutton.Width = 100;
mybutton.Height = 50;
mybutton.Click += (sender, ev) => { MessageBox.Show("Hello"); };
DockingManager dockmanager = new DockingManager();
//Set theme
dockmanager.Theme = new Xceed.Wpf.AvalonDock.Themes.ExpressionLightTheme();
//Create LayoutRoot
var layoutroot = new Xceed.Wpf.AvalonDock.Layout.LayoutRoot();
//Create LayoutPanel
var layoutpanel = new Xceed.Wpf.AvalonDock.Layout.LayoutPanel();
//Create LayoutDocumentPane
var layoutdocpane = new Xceed.Wpf.AvalonDock.Layout.LayoutDocumentPane();
//Create LayoutDocument and set parameters of Document
var LayoutDocument = new Xceed.Wpf.AvalonDock.Layout.LayoutDocument();
LayoutDocument.Title = "Some text";
//Put button in Document
LayoutDocument.Content = mybutton;
layoutdocpane.Children.Add(LayoutDocument);
layoutpanel.Children.Add(layoutdocpane);
layoutroot.RootPanel.Children.Add(layoutpanel);
dockmanager.Layout = layoutroot;
mainGrid.Children.Add(dockmanager);
Sorry for my poor English. Please rewrite this, if it would be helpful.
I'm not that familiar with WPF and especially AvalonDock. I did it like this and it works so far :)
You can write a separate class for your documents that inherits from LayoutDocument. In that way you should be able to edit the standard layout of your "Project-Document" with the VisualStudio Designer (add your stackpanel, canvas etc.).
(I assume that you have a standard way of displaying your "Project-Document". Otherwise you could build the content yourself in code behind like you would do in WPF and put it inside the LayoutDocument.)
For example:
<ad:LayoutDocument x:Class="Namespace.MyDocument"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ad="http://avalondock.codeplex.com"
d:DesignHeight="500"
d:DesignWidth="800"
<Grid>
<!-- content -->
</Grid>
</ad:LayoutDocument>
And the class in code behind that inherits from LayoutDocument:
namespace Namespace
{
public partial class MyDocument : AvalonDock.Layout.LayoutDocument
{
// ...
}
}
To create and add a new document you just instantiate a new MyDocument object and add it to the collection via binding or something like layoutDocumentPane.Children.Add(doc).
I don't know about the binding for the Title Property, though.
Thats exactly right.
You can add the title by just adding doc.Title = "My document title"
or
You can add Title="My document title" in the document.xaml which is going to be the child.
I'm new to WPF and I want to do an app which shows pictures in a ListBox.
I made a class called _Images, that gets images from a local folder, puts on a list.
namespace wpfAppSlides.Imagens
{
class _Images
{
public List<Image> imgList = new List<Image>();
public void CarregaImagens()
{
string dir = #"C:\Users\devUser\Img";
foreach (string file in Directory.GetFiles(dir))
{
Image image = new Image();
BitmapImage source = new BitmapImage();
source.BeginInit();
source.UriSource = new Uri(file, UriKind.Relative);
source.EndInit();
image.Source = source;
imgList.Add(image);
}
}
}
}
An then, in my XAML, I referenced my namespaces.
xmlns:is="clr-namespace:wpfAppSlides._Images"
xmlns:col="clr-namespace:wpfAppSlides"
And put in a DataContext.
<Window.DataContext>
<is:_Images></is:_Images>
</Window.DataContext>
But when I wanna feed my ListBox with the items on imgList, using ItemsSource (in Properties, not code), he does not find any Path that I can relate to imgList.
ListBox XAML:
<ListBox Height="110"
HorizontalAlignment="Left"
Margin="14,50,0,0"
Name="listBox1"
VerticalAlignment="Top"
Width="477" ItemsSource="{Binding}" />
MainWindow code:
public partial class MainWindow : Window
{
_Imagens imgs;
public MainWindow()
{
InitializeComponent();
imgs = (_Images)this.DataContext;
imgs.CarregaImagens();
}
}
I tried to use ObservableCollection, but it's no use.
Help? ):
I noticed a couple of things..
looks like your class _Images isn't declared as public
When constructor of that class is called (happens when you added it as Window.DataContext,
how/where does CarregaImagens() get called. Does it ever get called? If not, put in in the default constructor.
You shouldn't name a class with the underscore (that's the convention for a private member)
you know that in order to bind in xaml, the property cannot be private?
hoper these help...
I am trying to create a TreeView from the Silverlight TreeView control. I have my data being pulled from a WCF service that pulls from EF. All of the data is coming in fine. I have the page set up where I can input a UserName, click a button, and the data will populate the first generation in the TreeView. So, I'm dynamically building TreeViewItems to put into my TreeView with a Selected RoutedEventHandlers attached to each one. When I click on one of the TreeViewItem nodes, it kicks off the tvi_Selected function in which I want to populate TreeViewItems under the TreeViewItem that I just selected.
I run into problem when I am in my delegate function prox_GetChildMembersCompleted. I can't figure out a way to do a FindControl type lookup on the TreeViewItem that I want to add the child TreeViewItem elements to. So, I thought that I would just create a protected field where I would store the Header information to because it contain only the UserName. I just need to be able to access a specific TreeViewItem by Header or some other method that is alluding me.
You can see that in my Selected eventhandler, that I am getting the Header info by casting the sender object to a TreeViewItem. In the the delegate function prox_GetChildMembersCompleted that is called inside of tvi_Selected, the sender object is WCFDataClient so I can't grab the same data from that sender. Any insight into this would be much appreciated even if you suggest a method that is completely different.
<UserControl xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
x:Class="FloLOS2.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
<Grid x:Name="LayoutRoot" Background="#5C7590">
<StackPanel>
<TextBox x:Name="txtUserName" Width="120" Margin="5"></TextBox>
<TextBlock x:Name="txtFillBlock" Width="300" Margin="5" Foreground="White" Text="Change me"></TextBlock>
<Button x:Name="btnSubmit" Margin="5" Content="Get Frontline" Width="120" Click="btnSubmit_Click" />
<data:DataGrid x:Name="MembersGrid" Margin="5"></data:DataGrid>
<controls:TreeView x:Name="MembersTree" Margin="5"></controls:TreeView>
</StackPanel>
</Grid>
</UserControl>
namespace FloLOS2
{
public partial class MainPage : UserControl
{
string sParentID;
public MainPage()
{
InitializeComponent();
}
private void btnSubmit_Click(object sender, RoutedEventArgs e)
{
GetMyDataRef.GetMyDataClient prox = new FloLOS2.GetMyDataRef.GetMyDataClient();
prox.GetMembersCompleted += new EventHandler<FloLOS2.GetMyDataRef.GetMembersCompletedEventArgs>(prox_GetMembersCompleted);
prox.GetMembersAsync(txtUserName.Text);
}
void prox_GetMembersCompleted(object sender, FloLOS2.GetMyDataRef.GetMembersCompletedEventArgs e)
{
GetMyDataRef.Member[] members = e.Result.ToArray();
foreach (var x in members)
{
TreeViewItem tvi = new TreeViewItem() { Header = x.UserName };
tvi.Selected += new RoutedEventHandler(tvi_Selected);
MembersTree.Items.Add(tvi);
}
//MembersTree.Items.Add(tvi);
}
void prox_GetChildMembersCompleted(object sender, FloLOS2.GetMyDataRef.GetMembersCompletedEventArgs e)
{
GetMyDataRef.Member[] members = e.Result.ToArray();
TreeViewItem tviParent = new TreeViewItem();
// *** Find TreeViewItem control based on Header ***
foreach (var x in members)
{
TreeViewItem tviChild = new TreeViewItem() { Header = x.UserName };
tviChild.Selected += new RoutedEventHandler(tvi_Selected);
tviParent.Items.Add(tviChild);
}
}
void tvi_Selected(object sender, RoutedEventArgs e)
{
try
{
TreeViewItem item = (TreeViewItem)sender;
txtFillBlock.Text = item.Header.ToString();
sParentID = item.Header.ToString();
GetMyDataRef.GetMyDataClient prox = new FloLOS2.GetMyDataRef.GetMyDataClient();
prox.GetMembersCompleted += new EventHandler<FloLOS2.GetMyDataRef.GetMembersCompletedEventArgs>(prox_GetChildMembersCompleted);
prox.GetMembersAsync(item.Header.ToString());
}
catch (Exception ex)
{
txtFillBlock.Text = ex.InnerException.ToString();
}
}
}
}
I figured out a way to do it. I went and assigned a Name to the dynamically generated TreeViewItems as the UserName. I also stored the sender UserName in a protected string, then called this line of code to get the parent TreeViewItem:
TreeViewItem tviParent = (TreeViewItem)LayoutRoot.FindName(sParentID);
Thanks for what would have been great answers! :)