C# with WPF Call UserControl form from Window Form - c#

Actually, I'm using C# with WPF. Let me explain again:
I have create UserControl (WPF) with one Button (Click on Button to create Image and textBox (Like New Folder)).
And I have another Window form (WPF) with Button and I want to Click on Button in Window Form to do Action instead of Button in UserControl. Here is the code of UserControl:
private void btnNewRoom_Click(object sender, RoutedEventArgs e)
{
Image img = new Image();
img.VerticalAlignment = System.Windows.VerticalAlignment.Top;
img.Width = 100;
img.Height = 100;
var assemblyLocation = Assembly.GetExecutingAssembly().Location;
var applicationDirectory = System.IO.Path.GetDirectoryName(assemblyLocation);
img.Source = new BitmapImage(new Uri("/Resources/Images/folder.png", UriKind.RelativeOrAbsolute));
StackPanel sp = new StackPanel();
TextBox tb = new TextBox();
tb.Width = 120;
tb.Height = 25;
tb.Text = "New Folder";
sp.Children.Add(img);
sp.Children.Add(tb);
AddNewRoom.Children.Add(sp);
}
and It is possible ?
Note: Any good way to Click button to Create Image and TextBox?

Implement a static event handler in your WPF control, and simply call it from your Window Form's button click event.

Related

C# Custom ComboBox - DropDown Position

I'm creating a ComboBox control using ToolStripControlHost and ToolStripDropDown that can host any kind of control in the DropDown window. For example, the DropDown window might display a listview or treeview or even another usercontrol.
I'm posting a simplified code below where dropdown host a usercontrol with a listview and a button like this:
The problem occurs when the control is positioned at the bottom of the screen in such a way that the dropdown window will extrapolate the lower boundary of the screen. When this occurs, the dropdown ends up hiding the control.
In this case, I'd like to fix the _dropDown.Show method call to show dropdown window as follows:
To repeat the problem, just run the code below and drag the window to the bottom of the screen and open the dropdown.
using System;
using System.Windows.Forms;
public class CustomComboBox : UserControl
{
ToolStripDropDown _dropDown;
public CustomComboBox()
{
var textbox = new TextBox();
textbox.Location = new System.Drawing.Point(0, 0);
textbox.Size = new System.Drawing.Size(this.Width - 22, 20);
textbox.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
this.Controls.Add(textbox);
var button = new Button();
button.Location = new System.Drawing.Point(this.Width - 22, -1);
button.Size = new System.Drawing.Size(22, 22);
button.Text = "\u2BC6";
button.Anchor = AnchorStyles.Right | AnchorStyles.Top;
button.Click += new System.EventHandler(this.Button_Click);
this.Controls.Add(button);
var dropDownControl = new DropDownControlTest();
var controlHost = new ToolStripControlHost(dropDownControl);
_dropDown = new ToolStripDropDown();
_dropDown.AutoSize = true;
_dropDown.Items.Add(controlHost);
}
void Button_Click(object sender, EventArgs e)
{
_dropDown.Show(this, 0, this.Height);
}
}
public class DropDownControlTest : UserControl
{
public DropDownControlTest()
{
var listview = new ListView();
listview.Location = new System.Drawing.Point(3, 1);
listview.Size = new System.Drawing.Size(400,300);
listview.View = View.Details;
listview.Columns.Add("Col 1",100);
listview.Columns.Add("Col 2",100);
this.Controls.Add(listview);
var button = new Button();
button.Location = new System.Drawing.Point(3, 305);
button.Text = "More...";
this.Controls.Add(button);
}
}
public class Form1 : Form
{
private static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
public Form1 ()
{
CustomComboBox ccBox = new CustomComboBox();
ccBox.Location = new System.Drawing.Point(10, 10);
ccBox.Height = 20;
this.Text = "Test CustomComboBox";
this.Controls.Add(ccBox);
}
}
You can use the ToolStripDropDown.Show Method (Control, Point, ToolStripDropDownDirection) overload to control the drop direction. The code will need to perform bounds checking to decide whether to place the dropdown above or below the textbox.
The following is a simplistic method for doing the bounds checking and was only tested on a single screen configuration.
First, make textbox a class level variable.
private TextBox textbox;
public CustomComboBox()
{
//var textbox = new TextBox();
textbox = new TextBox();
The display logic is as follows.
void Button_Click(object sender, EventArgs e)
{
Point textBoxScreenLocation = textbox.PointToScreen(textbox.Location);
// try to position _dropDown below textbox
Point pt = textBoxScreenLocation;
pt.Offset(0, textbox.Height);
// determine if it will fit on the screen below the textbox
Size dropdownSize = _dropDown.GetPreferredSize(Size.Empty);
Rectangle dropdownBounds = new Rectangle(pt, dropdownSize);
if (dropdownBounds.Bottom <= Screen.GetWorkingArea(dropdownBounds).Bottom)
{ // show below
_dropDown.Show(pt, ToolStripDropDownDirection.BelowRight);
}
else
{ // show above
_dropDown.Show(textBoxScreenLocation, ToolStripDropDownDirection.AboveRight);
}
}
}
I can not comment that is why I am answering your question. You can use the reflection and then re-position you control. I have found a custom combobox control same as you developed. Please check this. At least, you will get some idea what you need to do.

Selecting image from StackPanel C# UWP (Adding action listener to UIElement and Image to UIElement)

I am using C# and I am creating UWP app.
I am using Windons.Ui.Xaml.Controls.Image and I have created follwoing code which lists my images
UxHelpers.DispatchToASTAThread(
async () =>
{
imageIndex++;
StackPanel stackPanel = new StackPanel();
stackPanel.Children.Add(image);
}
this.Results.Children.Add(stackPanel);
}).Forget();
This is in for loop, and I want when user clicks on certain image to be able to save it.
I have code for saving, I just don't know how to add mouse listener to each image, so that it is marked when I move mouse over it (So user knows that by clicking on it something will happen) and when he clicks I want it to call my function with this pictures index....
I have looked at UIElement but i still can't figure it out.
Thanks!!
We can add the PointerEntered event to the Image control that when the user move mouse over it then we can change the UI. Then we can add the Tapped event to the Image control, if the user click on it, it will be fired.
To get the index of the Image, we can set the index to the Name property of the Image.
For example:
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
StackPanel stackPanel = new StackPanel();
for (int i = 0; i < 3; i++)
{
Windows.Storage.Streams.IRandomAccessStream random = await Windows.Storage.Streams.RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/sun2set.jpg")).OpenReadAsync();
Image image = new Image();
BitmapImage bitmapImage = new BitmapImage();
StackPanel mystackPanel = new StackPanel();
image.Name = i.ToString();
bitmapImage.SetSource(random);
image.Source = bitmapImage;
mystackPanel.Children.Add(image);
image.PointerEntered += Image_PointerEntered;
image.PointerExited += Image_PointerExited;
stackPanel.Children.Add(mystackPanel);
}
this.Results.Children.Add(stackPanel);
}
private void Image_PointerExited(object sender, PointerRoutedEventArgs e)
{
var image = sender as Image;
var parent = VisualTreeHelper.GetParent(image) as StackPanel;
parent.BorderBrush = new SolidColorBrush(Colors.Red);
parent.BorderThickness = new Thickness(0);
image.Tapped -= Image_Tapped;
}
private void Image_PointerEntered(object sender, PointerRoutedEventArgs e)
{
var image = sender as Image;
Debug.WriteLine("The" + image.Name + "is Selected!");
var parent = VisualTreeHelper.GetParent(image) as StackPanel;
parent.BorderBrush = new SolidColorBrush(Colors.Red);
parent.BorderThickness = new Thickness(5);
image.Tapped += Image_Tapped;
}
private void Image_Tapped(object sender, TappedRoutedEventArgs e)
{
var image = sender as Image;
//download the image
}

How can I add buttons dynamically to a WPF application?

I am new to WPF and i want to create a window which will create a variable number of buttons with an image.
List<Button> HeroButtons = new List<Button>();
for (int i=0;i<20;i++)
HeroButtons.Add(new Button(){});
foreach( Button but in HeroButtons)
{
var brush = new ImageBrush();
brush.ImageSource = new BitmapImage(new Uri("Resources/lina.png", UriKind.Relative));
but.Background = brush;
}
Nothing appears if I run the application.
Give your grid or other container a name, then use that name (ie Grid1) to add children.
foreach (Button but in HeroButtons)
{
Grid1.Children.Add(but);
}

Reset focus to default after Popup LostFocus

I'm observing that when the Popup control loses focus it returns focus back to the object that initiated the Popup. So basically this sequence of events.
Textbox GotFocus fires and I open the popup
When finished with the Popup user clicks anywhere outside Popup to activate LostFocus
LostFocus activates, but immediately after GotFocus for the object in step 1 (Textbox) executes - relaunching the popup.
My question, is there a way to reset focus to whatever the default is when you first start an app? I want to prevent it from returning focus back to the control that launched the popup.
EDIT: I removed LostFocus event because I found it wasn't necessary in order to remove the popup from view when user taps away.
Popup p;
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
p = new Popup();
p.IsLightDismissEnabled = true;
//p.LostFocus += p_LostFocus;
}
private void m_GotFocus(object sender, RoutedEventArgs e)
{
if (p.IsOpen != true)
{
// Create some content to show in the popup. Typically you would
// create a user control.
Border border = new Border();
border.BorderBrush = new SolidColorBrush(Colors.Black);
border.BorderThickness = new Thickness(0);
StackPanel panel1 = new StackPanel();
panel1.FlowDirection = Windows.UI.Xaml.FlowDirection.LeftToRight;
panel1.Background = new SolidColorBrush(Color.FromArgb(255, 30, 30, 30));
Button button1 = new Button();
button1.Content = ".";
button1.Margin = new Thickness(5.0);
button1.BorderThickness = new Thickness(0);
button1.Background = new SolidColorBrush(Color.FromArgb(255, 90, 90, 90));
button1.Click += new RoutedEventHandler(Feedback_Click);
TextBlock textblock1 = new TextBlock();
textblock1.Text = "";
textblock1.TextWrapping = TextWrapping.WrapWholeWords;
textblock1.Margin = new Thickness(5.0);
panel1.Children.Add(textblock1);
panel1.Children.Add(button1);
border.Child = panel1;
// Set the Child property of Popup to the border
// which contains a stackpanel, textblock and button.
p.Child = border;
// Set where the popup will show up on the screen.
p.VerticalOffset = 400;
p.HorizontalOffset = 100;
// Open the popup.
p.IsOpen = true;
}
}

WPF drag and drop C# drag image as well

i dynamic populate a dock panel with answers from database and another dock panel with questions from the database as well. the answers will be populated as Labels and i trying to do a drag and drop with labels to textblock . Yes i can drag and drop , but the thing is i want to drag the label too . For example if the Label content is Hello , i want the hello to be dragged over with the word " hello " as well , for now , when i drag it , it doesn't drag the word as well , but when i drop it into a textbox , the word " hello " is dropped . I want to drag the animation or word as well together with the cursor .
this is my code :
private void PopulateQuestion(int activityID, int taskID)
{
IList<Model.question> lstQuestion = qn.GetRecords(taskID, activityID);
StackPanel sp = new StackPanel();
StackPanel stp = new StackPanel();
foreach (Model.question qhm in lstQuestion)
{
StackPanel sp1 = new StackPanel() { Orientation = Orientation.Horizontal }; // Question
TextBlock tb = new TextBlock();
tb.Text = qhm.QuestionContent;
tb.FontWeight = FontWeights.Bold;
tb.FontSize = 24;
sp1.Children.Add(tb);
StackPanel sp2 = new StackPanel() { Orientation = Orientation.Horizontal }; // Answer
Label tb1 = new Label();
tb1.Content = qhm.Answer;
tb1.FontWeight = FontWeights.Bold;
tb1.FontSize = 24;
tb1.MouseLeftButtonDown += tb1_Click;
sp2.Children.Add(tb1);
TextBox tbox = new TextBox();
tbox.Width = 100;
tbox.FontSize = 24;
tbox.AllowDrop = true;
tbox.FontWeight = FontWeights.Bold;
if (qhm.Answer.Trim().Length > 0 )
{
sp1.Children.Add(tbox);
}
sp.Children.Add(sp1);
stp.Children.Add(sp2);
}
dockQuestion.Children.Add(sp);
dockAnswer.Children.Add(stp);
}
private void tb1_Click(object sender, RoutedEventArgs e)
{
Label lbl = (Label)sender;
DataObject dataObj = new DataObject(lbl.Content);
DragDrop.DoDragDrop(lbl, dataObj, DragDropEffects.All);
lbl.IsEnabled = false;
lbl.Foreground = (SolidColorBrush)new BrushConverter().ConvertFromString("#FFFB3B46"); // Red
}
You can follow the strategy outlined in the link below, which essentially creates a new window and causes the window position to be updated with the mouse cursor.
http://blogs.msdn.com/b/jaimer/archive/2007/07/12/drag-drop-in-wpf-explained-end-to-end.aspx
So the main points from the page are that you decorate the cursor using the Adorner.
You can use the this.DragSource.GiveFeedback and other events on the DragSource event handlers to set up the Adorner.
Once you have the event handler, that gives you the opportunity to do something.
//Here we create our adorner..
_adorner = new DragAdorner(DragScope, (UIElement)this.dragElement, true, 0.5);
_layer = AdornerLayer.GetAdornerLayer(DragScope as Visual);
_layer.Add(_adorner);
So you can create your own Adorner by subclassing it. You can find more info on creating a custom adorner here:
http://msdn.microsoft.com/en-us/library/ms743737.aspx
take a look at this
http://blogs.msdn.com/b/adamroot/archive/2008/02/19/shell-style-drag-and-drop-in-net-wpf-and-winforms.aspx
the default wpf drag & drop's animation is ugly, if you want be show some text or image while dragging,you need
do something more.

Categories