I have some itemsControl that i dynamicly adding to it StackPanel as an item.
Each of the StackPanel contain 2 button - btn1, btn2.
I dynamicly connect each button to some button event ( all the button event are same ).
When i test it - i see that the event is not call on the button click - and i dont see any reason to this.
the Code:
private StackPanel CreatePanel()
{
StackPanel stackPanel = new StackPanel();
stackPanel.Orientation = Orientation.Horizontal;
for (int i = 0; i < 2; i++)
{
Button btn = new Button();
btn.Height = btn.Width = 100;
btn.Content = i % 2 == 0 ? "Btn1" : "Btn2";
// Event connection
btn.Click += new RoutedEventHandler( button1_Click );
stackPanel.Children.Add(btn);
}
return stackPanel;
}
From MSDN: For certain combinations of input events and WPF control classes, the element that raises the event is not the first element that has the opportunity to handle it.
This is the nature of the RoutedEventHandler:)
try below code , works for me Please note grd is a Grid on my XAML
Edited added code for ItemsControl
XAML
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<ScrollViewer >
<Grid>
<ItemsControl Name="grd">
</ItemsControl>
</Grid>
</ScrollViewer>
Code
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
grd.Items.Add(CreatePanel()); // Now grd is a itemsControl
}
private StackPanel CreatePanel()
{
StackPanel stackPanel = new StackPanel();
stackPanel.Orientation = Orientation.Horizontal;
for (int i = 0; i < 2; i++)
{
Button btn = new Button();
btn.Height = btn.Width = 100;
btn.Content = i % 2 == 0 ? "Btn1" : "Btn2";
// Event connection
btn.Click += new RoutedEventHandler(doCall);
stackPanel.Children.Add(btn);
}
return stackPanel;
}
private void doCall(object sender, RoutedEventArgs e)
{
MessageBox.Show("Hi");
}
}
Related
I'm trying to use TestStack.White to simulate a click on a menu subitem in a WPF application. That subitem is added at runtime, and I have little control over how it's created. I don't seem to be able to find the menu subitem to click.
I have tried this:
MainWindow.xaml
<Window x:Class="WpfApplication3.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" Loaded="Window_Loaded">
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem x:Name="MainMenu" Header="Menu">
<MenuItem x:Name="SubMenu" Header="Sub Menu"/>
</MenuItem>
</Menu>
</DockPanel>
</Window>
MainWindow.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 5; i++)
{
var newItem = new MenuItem();
newItem.Header = string.Format("Item {0}", i + 1);
newItem.Name = string.Format("Item{0}", i + 1);
this.SubMenu.Items.Add(newItem);
newItem.Click += new RoutedEventHandler(MenuItemClickHandler);
}
}
private void MenuItemClickHandler(object sender, RoutedEventArgs e)
{
var menuItem = (MenuItem)sender;
MessageBox.Show(this, "You clicked " + menuItem.Header, "Menu Click", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
ConsoleApplication1.Program
class Program
{
static void Main(string[] args)
{
string path = #"C:\{path}\WpfApplication3\bin\Debug";
string prog = Path.Combine(path, "WpfApplication3.exe");
TestStack.White.Application app = TestStack.White.Application.Launch(prog);
var window = app.GetWindow(SearchCriteria.ByText("MainWindow"), InitializeOption.WithCache);
window.WaitWhileBusy();
var menu = window.MenuBar.MenuItem("Menu", "SubMenu", "Item2");
menu.Click();
}
}
I'm unsure how to find the menu subitems, and I'm guessing its because they weren't there when the application was compiled ?
Apologies for the Noddy example, but WPF isn't my forte, and neither is TestStack.White
Here's where I got to (which works), but why are the added menu items "ChildMenus", and not findable in the same way the "menu" and "sub menu" are found ? Also, why is the child menu found by a name of "item 2" (and not, as I thought would be the case, of "item2") ? Why the apparent mix up of "name" and "header" used in the xaml ?
//var menu = window.MenuBar.MenuItem("Menu", "SubMenu", "Item2");
var menu = window.MenuBar.MenuItem("Menu", "Sub Menu");
var menus = menu.ChildMenus;
menu = menus.First(m => m.Name == "Item 2");
menu.Click();
I was making a WPF application with Windows style = None, I managed to create and work exit button in my window but i don't know how to make it drag able while pressing left mouse button.
I have created Mouse left button down event in .cs file as below:
private void see(object sender, MouseButtonEventArgs e)
{
this.DragMove();
}
Then I added border in .xaml file to do dragging of the window as below:
<Grid>
<Border BorderThickness="2" BorderBrush="Black" Height="120" Width="100" MouseLeftButtonDown="see" />
</Grid>
Now i don't understand what is the problem here? I will be very thankful if someone help me in this ?
Use a similar pattern to this Window:
public class DragableWindowNoStyle : Window
{
public DragableWindowNoStyle()
{
WindowStyle = WindowStyle.None;
Grid grid = new Grid() { };
_moveBorder = new Border()
{
BorderThickness = new Thickness(2),
BorderBrush = Brushes.Red,
Background = Brushes.Black,
Width = 50,
Height = 20,
HorizontalAlignment= System.Windows.HorizontalAlignment.Center,
VerticalAlignment = System.Windows.VerticalAlignment.Top,
};
grid.Children.Add(_moveBorder);
this.Content = grid;
_moveBorder.PreviewMouseLeftButtonDown += _moveBorder_PreviewMouseLeftButtonDown;
}
Point _startPoint;
bool _isDragging = false;
Border _moveBorder;
private void _moveBorder_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (Mouse.Capture(this))
{
_isDragging = true;
_startPoint = PointToScreen(Mouse.GetPosition(this));
}
}
protected override void OnPreviewMouseMove(MouseEventArgs e)
{
if (_isDragging)
{
Point newPoint = PointToScreen(Mouse.GetPosition(this));
int diffX = (int)(newPoint.X - _startPoint.X);
int diffY = (int)(newPoint.Y - _startPoint.Y);
if (Math.Abs(diffX) > 1 || Math.Abs(diffY) > 1)
{
Left += diffX;
Top += diffY;
InvalidateVisual();
_startPoint = newPoint;
}
}
}
protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e)
{
if (_isDragging)
{
_isDragging = false;
Mouse.Capture(null);
}
}
}
There is an example of how to create a custom window with resize, drag, minimize, restore and close functionality from scratch available here:
How to create a custom window in WPF: https://blog.magnusmontin.net/2013/03/16/how-to-create-a-custom-window-in-wpf/
You could also customize a window while retaining its standard functionality using the WindowChrome class: https://msdn.microsoft.com/en-us/library/system.windows.shell.windowchrome(v=vs.110).aspx. Then you don't have to implement the resize and drag functionality yourself.
I am trying to use canvas inside windows form and zoom and pan that canvas for that first i put element host and then put canvas inside it and then put picture box in canvas and then trying to zoom canvas i have tried various ways but event of any control does not executed i have also written all mouse wheel events but no one is executed so please suggest me solution below is my code for adding controls and mouse wheel events
elementHost1.Height = picVarify.Height;
elementHost1.Width = picVarify.Width;
elementHost1.Location = picVarify.Location;
touchcanvas = new System.Windows.Controls.Canvas();
WindowsFormsHost hst = new WindowsFormsHost();
hst.Name = "Host";
hst.Child = picVarify;
hst.Height = picVarify.Height;
hst.Width = picVarify.Width;
touchcanvas.Height = picVarify.Height;
touchcanvas.Width = picVarify.Width;
touchcanvas.Children.Add(hst);
zm = new ZoomAndPan.ZoomAndPanControl();
zm.Name = "zm";
zm.Content = touchcanvas;
zm.MouseWheel += new System.Windows.Input.MouseWheelEventHandler(zoomAndPanControl_MouseWheel);
elementHost1.Child = zm;
touchcanvas.MouseWheel += new System.Windows.Input.MouseWheelEventHandler(touchcanvas_MouseWheel);
hst.MouseWheel += new System.Windows.Input.MouseWheelEventHandler(hst_MouseWheel);
picVarify.MouseWheel += new MouseEventHandler(picverify_MouseWheel);
here is the code that's working fine for me. I added canvas inside a canvas and set background property of both canvases.
XAML
<Window x:Class="WpfStack.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 x:Name="rootGrid" Margin="10,0,0.4,3.8">
<Canvas Name="BaseCanvas" Background="AliceBlue" Margin="10,0,0,10">
</Canvas>
</Grid>
Code
public MainWindow()
{
InitializeComponent();
Canvas touchcanvas = new System.Windows.Controls.Canvas();
touchcanvas.Height =100;
touchcanvas.Width = 100;
touchcanvas.Background = Brushes.Transparent;
touchcanvas.MouseWheel += new System.Windows.Input.MouseWheelEventHandler(touchcanvas_MouseWheel);
BaseCanvas.Children.Add(touchcanvas);
BaseCanvas.Background = Brushes.Transparent;
}
public void touchcanvas_MouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs args)
{
args.Handled = true;
}
I need that if my pop up window appear (after click) , the main window brightness has to decrease, maybe someone know how to do it?
Example:
EDIT: I create canvas, but do not know how to use it, brightness need decrease then pop up appear.
code:
private void sample_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string path1 = System.AppDomain.CurrentDomain.BaseDirectory + "../../loader_bg.png";
string path2 = System.AppDomain.CurrentDomain.BaseDirectory + "../../loader.gif";
ImageBrush myBrush = new ImageBrush();
Image image = new Image();
image.Source = new BitmapImage(
new Uri(path1));
myBrush.ImageSource = image.Source;
Image ima = new Image();
MediaElement gif = new MediaElement();
ima.Source = new BitmapImage(new Uri(path1));
gif.Source=new Uri(path2);
gif.Height = 72;
gif.Width = 72;
var pop = new Popup
{
IsOpen = true,
StaysOpen = false,
AllowsTransparency = true,
VerticalOffset = 350,
HorizontalOffset = 700,
Height = 128,
Width = 128,
};
Canvas c=new Canvas();
c.Background=Brushes.Black;
c.Opacity = 0.6;
Grid p = new Grid();
p.Background = myBrush;
//p.Children.Add(ima);
//p.Children.Add(c);
p.Children.Add(gif);
pop.Child = p;
}
}
EDIT 2:
I have the same question only my code is change. Now I created new xaml.cs for pop up window, and try to achieve the same purpose, but I do not get the same (I talk about brightness decrease).
Its my new xaml.cs :
namespace uploader
{
/// <summary>
/// Interaction logic for PopupPanel.xaml
/// </summary>
public partial class PopupPanel : UserControl
{
private Popup _currentPopup;
public PopupPanel()
{
InitializeComponent();
string path1 = System.AppDomain.CurrentDomain.BaseDirectory + "../../loader_bg.png";
string path2 = System.AppDomain.CurrentDomain.BaseDirectory + "../../loader.gif";
ImageBrush myBrush = new ImageBrush();
Image image = new Image();
image.Source = new BitmapImage(new Uri(path1));
myBrush.ImageSource = image.Source;
MediaElement gif = new MediaElement();
gif.Source=new Uri(path2);
gif.Height = 72;
gif.Width = 72;
_currentPopup = new Popup
{
StaysOpen = false,
AllowsTransparency = true,
VerticalOffset = 350,
HorizontalOffset = 700,
Height = 128,
Width = 128,
};
Overlay.Visibility = Visibility.Visible;
_currentPopup.Closed += PopupClosing;
_currentPopup.IsOpen = true;
Grid p = new Grid();
p.Background = myBrush;
p.Children.Add(gif);
_currentPopup.Child = p;
}
private void PopupClosing(object sender, EventArgs e)
{
_currentPopup.Closed -= PopupClosing;
_currentPopup = null;
Overlay.Visibility = Visibility.Collapsed;
}
}
}
My Mainwindow.xaml.cs:
namespace uploader
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void sample_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
PopupPanel pop = new PopupPanel();
}
...
I do this in all my WPF applications by using a Canvas with black background and opacity
Example:
<Window>
<Grid>
<!--Main content-->
<UserControl/>
<Grid>
<Canvas Background="Black" Opacity="0.6"/>
<!--Overlay content-->
<UserControl VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</Grid>
</Window>
Using your current code, you will need to handle the visibility of the Canvas overlay.
It's easier to to have it defined within your XAML as shown below:
<Window>
<Grid>
<!--Main content-->
<UserControl/>
<Grid>
<Canvas x:Name="Overlay"
Background="Black"
Opacity="0.6"
Visibility="Collapsed"/>
<!--Overlay content-->
<UserControl VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</Grid>
</Window>
Then, in your code-behind you can set the visibility before the popup opens, and when it closes:
Popup _currentPopup;
private void sample_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
...
_currentPopup = new Popup
{
StaysOpen = false,
AllowsTransparency = true,
VerticalOffset = 350,
HorizontalOffset = 700,
Height = 128,
Width = 128
};
Overlay.Visibility = Visibility.Visible;
_currentPopup.Closed += PopupClosing;
_currentPopup.IsOpen = true;
}
private void PopupClosing(object sender, EventArgs e)
{
_currentPopup.Closed -= PopupClosing;
_currentPopup = null;
Overlay.Visibility = Visibility.Collapsed;
}
Note, that I am using a local variable to keep a reference to the popup. This is so that I can un-subscribe from the Closing event (helps prevent memory leaks)
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
System.Windows.Controls.Button b = new System.Windows.Controls.Button();
System.Windows.Shapes.Rectangle r = new System.Windows.Shapes.Rectangle();
r.Width = 40;
r.Height = 40;
r.Fill = System.Windows.Media.Brushes.Black;
b.Content = r; // Make the square the content of the Button
this.AddChild(b);
}
}
I have code for button from some WPF 4 book, and i want to display from here ( not from XAML), but when i want to add button 'b' as a child of main window i get exception and info : Content of a ContentControl must be a single element.
How can i display it in c#?
As you say this line
this.AddChild(b);
wont work as the error points out it requires a single element (ie Grid, StackPanel)
Give your Grid in xaml a name
MainWindow.xaml
<Grid x:Name="root">
</Grid>
and add your button to the Grid in MainWindow.xaml.cs
//this.AddChild(b); //wont work cant add button to this(MainWindow)
root.Children.Add(b); //adds button to the Grid of MainWindow