PDA

View Full Version : How To Reference UI Element Created Programmatically?



psychman
March 27th, 2009, 07:49 PM
Hello. I am trying to create some click events for UI Elements (Images) I am creating programmatically. The problem I am having is that I am not sure how to reference those objects once they have been created. I tried moving the statement I used to create the image "Image myImage = new Image;" out of the method and up to the class level, but I get an error that reads, "Specified Visual is already a child of another Visual or the root of a CompositionTarget". I did not have any luck with this question over on the MSDN boards, but I imagine there must be a straight forward solution...it is just a little further up the learning curve than the position I am at right now!


Here is the code I have been playing with:



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.IO;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Forms;
using System.Collections.ObjectModel;
using Microsoft.Win32;
namespace WpfApplication1
{
///<summary>
/// Interaction logic for Window1.xaml
///</summary>
publicpartialclassWindow1 : Window
{
public Window1()
{
this.InitializeComponent();
this.DataContext = this;
}
//I am trying to get access to these "myImage" objects once they are displayed on myCanvas
Image myImage = newImage();
ObservableCollection<MyImage> _images = newObservableCollection<MyImage>();
publicObservableCollection<MyImage> Images
{
get { return _images; }
set { _images = value; }
}
privateObservableCollection<MyImage> testTest(string directory)
{
ObservableCollection<MyImage> images = newObservableCollection<MyImage>();
DirectoryInfo di = newDirectoryInfo(directory);
List<FileInfo> lFi = newList<FileInfo>();
lFi.AddRange(di.GetFiles());
lFi = lFi.FindAll(delegate(FileInfo f)
{
return f.Extension.ToLower() == ".jpg" ||
f.Extension.ToLower() == ".tif" || f.Extension.ToLower() == ".bmp"
|| f.Extension.ToLower() == ".png";
});
foreach (FileInfo fi in lFi)
{
images.Add(newMyImage(newBitmapImage(newUri(fi.Ful lName)), fi.FullName));
//Here is where I commented-out myImage. The app works when myImage is here, but when
//I move it up to the class level I get an error that points to the code below that
//reads, "myCanvas.Children.Add(myImage);

//Image myImage = new Image();
myImage.Width = 75;
BitmapImage myBitmapImage = newBitmapImage();
myBitmapImage.BeginInit();
myBitmapImage.UriSource = newUri(fi.FullName);
myBitmapImage.EndInit();
myImage.Source = myBitmapImage;
myCanvas.Children.Add(myImage);
}
return images;
}
privateObservableCollection<MyImage> testTest()
{
System.Windows.Forms.FolderBrowserDialog fbDialog = new System.Windows.Forms.FolderBrowserDialog();
string mySavePath = fbDialog.SelectedPath.ToString();
if (fbDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
return testTest(fbDialog.SelectedPath);
}
returnnewObservableCollection<MyImage>();
}
//opens folder browser
privatevoid Button2_Click(object sender, RoutedEventArgs e)
{
testTest();
}
}
publicclassMyImage
{
privateImageSource _image;
privatestring _filename;
publicImageSource ImageSource
{
get { return _image; }
set { _image = value; }
}
publicstring Filename
{
get { return _filename; }
set { _filename = value; }
}
public MyImage(ImageSource image, string filename)
{
_image = image;
_filename = filename;
}
}
}


<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication1.Window1"
x:Name="Window"
Title="Window1"
Width="640" Height="480" xmlns:d="http://schemas.microsoft.com/expression/blend/2008">
<Grid x:Name="LayoutRoot">
<Button HorizontalAlignment="Right" Margin="0,0,21,19" VerticalAlignment="Bottom" Width="89" Height="35" Content="Import" x:Name="Button2" Click="Button2_Click" />
<Canvas Margin="14,10,123,19" x:Name="myCanvas"></Canvas>
</Grid>
</Window>

psychman
March 28th, 2009, 12:29 AM
I just had a response back from the MSDN boards that I need to hit test to find out which UI Element is being clicked. I will explore this route and will hopefully find an answer to post here.

kirupa
March 28th, 2009, 04:42 AM
I just had a response back from the MSDN boards that I need to hit test to find out which UI Element is being clicked. I will explore this route and will hopefully find an answer to post here.
In the event handler for the UI element you click, simply do a cast such as "sender as UIElement". That will give you a reference to the element you are trying to find.

:thumb:

psychman
March 30th, 2009, 07:13 PM
In the event handler for the UI element you click, simply do a cast such as "sender as UIElement". That will give you a reference to the element you are trying to find.

:thumb:

Big thanks! I forgot about the random button app you created using this exact concept. http://www.kirupa.com/forum/showthread.php?t=250392

psychman
April 1st, 2009, 08:28 PM
Also, regarding this matter, how would I set this up if I wanted a rotate transform to happen to an Image object when a context menu item is clicked; not the image itself? I have been playing around with a setup in which I cast the sender as an Image and then using two If statements to check which context menu item was clicked. I will then apply either a clockwise or counter clockwise rotate transform based on which context menu item was clicked. The problem I am running into is how to write the condition for the If statement, undoubtedly due to my lack of C# experience. The following does not work because it says "click" can only be on the left of a += or -=. Here is the code:


//code from other private method
...myImage.MouseRightButtonUp += new MouseButtonEventHandler(myImage_MouseRightButtonUp );

void myImage_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{

Image clickedImage = (Image)sender;

if (contextRotateCW.Click == true)
{
//code to rotate "clickedImage" clockwise
}
if (contextRotateCCW.Click == true)
{
//code to rotate "clickedImage" counter clockwise
}
}