Event Triggers not working in Code Behind - c#

I want create WPF controls at Runtime dynamically. In the below code, I have added StackPanel at XAML and crated Button/TextBlock/Triggers at code behind. I want to see TextBlock under button at MouseEnter action and want to hide TextBlock at MouseLeave action.
This is not working as expected.
If add Button/Textblock code at XAML (commented now) Instead of creating them at Code behind(un commented now) then it is working fine.
Please let me know how to fix this? Not able understand why this not working If I create the button at runtime instead of XAML code. Thanks
XAML
<Grid>
<StackPanel Name="stackPanel5" >
<!--
<Button Name="Button1" Cursor="Hand" Content="Press Me"/>
<Border x:Name="TooltipBrd" BorderBrush="Black" BorderThickness="10,0,10,10" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Collapsed">
<TextBlock Margin="0,10,0,0" x:Name="myTextBlock" Text="Coded Test" />
</Border>
-->
</StackPanel>
</Grid>
code
public void LoadData()
{
//VisualState vs = new VisualState();
//vs.SetValue(FrameworkElement.NameProperty, YourStateName);
Button Button1 = new Button() { Cursor = Cursors.Hand, Content = "Press Me!" };
stackPanel5.Children.Add(Button1);
Border TooltipBrd = new Border()
{
BorderBrush = Brushes.Black,
BorderThickness = new Thickness(10, 10, 10, 10),
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Visibility = Visibility.Collapsed
};
TextBlock txtB1 = new TextBlock() { Text = "Lakshman", Margin = new Thickness(0, 100, 0, 0) };
TooltipBrd.Child = txtB1;
stackPanel5.Children.Add(TooltipBrd);
System.Windows.Interactivity.EventTrigger trigger1 = new System.Windows.Interactivity.EventTrigger();
trigger1.EventName = "MouseEnter";
ChangePropertyAction action1 = new ChangePropertyAction();
action1.TargetName = "TooltipBrd";
action1.PropertyName = "Visibility";
action1.Value = Visibility.Visible;
trigger1.Actions.Add(action1);
trigger1.Attach(Button1);
System.Windows.Interactivity.EventTrigger trigger2 = new System.Windows.Interactivity.EventTrigger();
trigger2.EventName = "MouseLeave";
ChangePropertyAction action2 = new ChangePropertyAction();
action2.TargetName = "TooltipBrd";
action2.PropertyName = "Visibility";
action2.Value = Visibility.Collapsed;
trigger2.Actions.Add(action2);
trigger2.Attach(Button1);
}

At the XAML, create the event like this
<Button x:Name="sample_btn" MouseEnter="sample_btn_MouseEnter" />
now at the code behind,
private void logOut_btn_MouseEnter(object sender, MouseEventArgs e)
{
//your logic on mouse enter
}
Similarly, do for mouse leave and you are good to go.

Magnus(MM8) - Given beautiful solution for this.
https://social.msdn.microsoft.com/profile/magnus%20(mm8)/?ws=usercard-mini
**Just set the TargetObject property of the actions to TooltipBrd and your code will work:**
public void LoadData() {
//VisualState vs = new VisualState();
//vs.SetValue(FrameworkElement.NameProperty, YourStateName);
Button Button1 = new Button() { Cursor = Cursors.Hand, Content = "Press Me!" };
stackPanel5.Children.Add(Button1);
Border TooltipBrd = new Border() {
BorderBrush = Brushes.Black,
BorderThickness = new Thickness(10, 10, 10, 10),
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Visibility = Visibility.Collapsed
};
TextBlock txtB1 = new TextBlock() { Text = "Lakshman", Margin = new Thickness(0, 100, 0, 0) };
TooltipBrd.Child = txtB1;
stackPanel5.Children.Add(TooltipBrd);
System.Windows.Interactivity.EventTrigger trigger1 = new System.Windows.Interactivity.EventTrigger();
trigger1.EventName = "MouseEnter";
ChangePropertyAction action1 = new ChangePropertyAction();
action1.**TargetObject** = TooltipBrd;
action1.PropertyName = "Visibility";
action1.Value = Visibility.Visible;
trigger1.Actions.Add(action1);
trigger1.Attach(Button1);
System.Windows.Interactivity.EventTrigger trigger2 = new System.Windows.Interactivity.EventTrigger();
trigger2.EventName = "MouseLeave";
ChangePropertyAction action2 = new ChangePropertyAction();
action2.**TargetObject** = TooltipBrd;
action2.PropertyName = "Visibility";
action2.Value = Visibility.Collapsed;
trigger2.Actions.Add(action2);
trigger2.Attach(Button1);
}
**If you set the TargetName property you need to call the RegisterName method on the StackPanel:**
int i = 0;
public void LoadData()
{
++i;
//VisualState vs = new VisualState();
//vs.SetValue(FrameworkElement.NameProperty, YourStateName);
Button Button1 = new Button() { Cursor = Cursors.Hand, Content = "Press Me!", Height = 150, Width=150 };
stackPanel5.Children.Add(Button1);
Border TooltipBrd = new Border()
{
BorderBrush = Brushes.Black,
BorderThickness = new Thickness(10, 10, 10, 10),
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Visibility = Visibility.Collapsed
};
TextBlock txtB1 = new TextBlock() { Text = "Lakshman", Margin = new Thickness(0, 100, 0, 0) };
TooltipBrd.Child = txtB1;
stackPanel5.Children.Add(TooltipBrd);
System.Windows.Interactivity.EventTrigger trigger1 = new System.Windows.Interactivity.EventTrigger();
trigger1.EventName = "MouseEnter";
ChangePropertyAction action1 = new ChangePropertyAction();
//action1.TargetObject = TooltipBrd;
action1.TargetName = "TooltipBrd"+i;
action1.PropertyName = "Visibility";
action1.Value = Visibility.Visible;
trigger1.Actions.Add(action1);
trigger1.Attach(Button1);
System.Windows.Interactivity.EventTrigger trigger2 = new System.Windows.Interactivity.EventTrigger();
trigger2.EventName = "MouseLeave";
ChangePropertyAction action2 = new ChangePropertyAction();
action2.TargetName = "TooltipBrd"+i;
//action2.TargetObject = TooltipBrd;
action2.PropertyName = "Visibility";
action2.Value = Visibility.Collapsed;
trigger2.Actions.Add(action2);
trigger2.Attach(Button1);
**stackPanel5.RegisterName("TooltipBrd"+i, TooltipBrd);**
}
When you are creating controls dynamically, you have to call the RegisterName method for the runtime or you to be able to find them using this name.

Related

Popup in WPF does not open

I have a datagrid with modified column header which contain a button which shall open a popup.
This is written in code behind because of different data sources with different number of columns.
That's how it looks like:
Popups are stored in:
Dictionary<string, Popup> HeaderPopups = new Dictionary<string, Popup>();
And here the code behind:
dgMaterials.AutoGeneratingColumn += (ss, ee) =>
{
Button b = new Button() { Content = "...", Name = "btn_" + ee.PropertyName, Margin = new Thickness(3) };
b.Click += HeaderFilterButtonClick;
StackPanel stackPanel = new StackPanel() { Orientation = Orientation.Horizontal };
stackPanel.Children.Add(new TextBlock() { Text = ee.PropertyName, VerticalAlignment = VerticalAlignment.Center });
stackPanel.Children.Add(b);
ee.Column.Header = stackPanel;
Popup pop = new Popup() { Name = "pop_" + ee.PropertyName, Placement = PlacementMode.Bottom, PlacementTarget = b, StaysOpen = false, Width = 200, Margin = new Thickness(3) };
Border bord = new Border() { Background = Brushes.White, BorderBrush = Brushes.Gray, BorderThickness = new Thickness(1,1,1,1) };
pop.DataContext = bord;
HeaderPopups.Add(ee.PropertyName, pop);
StackPanel stack = new StackPanel() { Margin = new Thickness(5, 5, 5, 15) };
bord.DataContext = stack;
StackPanel stackButtons = new StackPanel() { Orientation = Orientation.Horizontal, Margin = new Thickness(0, 0, 0, 15) };
Button bAll = new Button() { Margin = new Thickness(0, 0, 0, 0), Name = "btnAll_" + ee.PropertyName };
bAll.Click += btnAllClick;
TextBlock txtAll = new TextBlock() { Text = "Select All", Foreground = Brushes.Blue, Cursor = Cursors.Hand };
bAll.Content = txtAll;
Button bNone = new Button() { Margin = new Thickness(10, 0, 0, 0), Name = "btnNone_" + ee.PropertyName };
bNone.Click += btnNoneClick;
TextBlock txtNone = new TextBlock() { Text = "Select None", Foreground = Brushes.Blue, Cursor = Cursors.Hand };
bNone.Content = txtNone;
stackButtons.Children.Add(bAll);
stackButtons.Children.Add(bNone);
ListBox list = new ListBox() { Name = "lst_" + ee.PropertyName, BorderThickness = new Thickness(0) };
stack.Children.Add(stackButtons);
stack.Children.Add(list);
};
So for each column a popup is generated and I have the popups with the keys Spec_No, Grade and Class in my HeaderPopups dictionary.
I want the appropriate popups to show up beneath the clicked button, like in the example from http://www.jarloo.com/excel-like-autofilter-in-wpf/
Look here:
My problem is to open these popups in HeaderFilterButtonClick-Event. I tried it with:
private void HeaderFilterButtonClick(object sender, RoutedEventArgs e)
{
Button b = sender as Button;
txtTest.Text += e.OriginalSource.ToString() + Environment.NewLine;
txtTest.Text += e.Source.ToString() + Environment.NewLine;
txtTest.Text += b.Name;
if (b.Name == "btn_Spec_No")
{
HeaderPopups["Spec_No"].IsOpen = true;
}
}
but it doesn't work.
Can anybody help?
Your Popup is currently empty and thus completely invisible.
You should set the Child property of it to the Border and also set the Child property of the Border to something for it to render:
Popup pop = new Popup() { ... };
Border bord = new Border() { Background = Brushes.White, BorderBrush = Brushes.Gray, BorderThickness = new Thickness(1, 1, 1, 1) };
bord.Child = new TextBlock() { Text = "some content..." };
pop.Child = bord;
The popup is opening and rendering, but it is empty, so it can't be seen.
the problem is here
Border bord = new Border() { Background = Brushes.White, BorderBrush = Brushes.Gray, BorderThickness = new Thickness(1,1,1,1) };
pop.DataContext = bord;
Datacontext is used to set Binding targets, which an empty popup has no bindings.
You need the fill the child object instead by changing the above into
Border bord = new Border() { Background = Brushes.White, BorderBrush = Brushes.Gray, BorderThickness = new Thickness(1,1,1,1) };
pop.Child = bord;
this sets the root of the popup container to ther Border object.
You will also have to do the same with the stack panel and border
StackPanel stack = new StackPanel() { Margin = new Thickness(5, 5, 5, 15) };
bord.Child = stack;

Test if TextBox Exists C# WPF

I would like to test if a TextBox created earlier in the code exists. This TextBox is created in a "if test", this is why I want to test if it exists. But I don't know how I can test if it exists because I can't call the TextBox name because it doesn't exists..
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (((ComboBoxItem)typeproduit.SelectedItem).Content.ToString() == "Isolant")
{
TextBox EpIsolant = new TextBox
{
Width = 100,
Height = 29,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Top,
Margin = new Thickness(209, 294, 0, 0)
};
MyPage.Children.Add(EpIsolant);
Label EpIsolantLabel = new Label
{
Content = "Ep isolant (mm)",
Width = 100,
Height = 29,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Top,
Margin = new Thickness(209, 260, 0, 0)
};
MyPage.Children.Add(EpIsolantLabel);
}
else
{
// I want to test it here
// And if it exists, I want to remove it from MyPage.Children
}
}
Thanks for helping ! I couldn't find any help with Google
PS : When I try to change visibility, it's still not working:
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
TextBox EpIsolant = new TextBox
{
Width = 100,
Height = 29,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Top,
Margin = new Thickness(209, 294, 0, 0)
};
MyPage.Children.Add(EpIsolant);
Label EpIsolantLabel = new Label
{
Content = "Ep isolant (mm)",
Width = 100,
Height = 29,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Top,
Margin = new Thickness(209, 260, 0, 0)
};
MyPage.Children.Add(EpIsolantLabel);
EpIsolant.Visibility = Visibility.Hidden;
EpIsolantLabel.Visibility = Visibility.Hidden;
if (((ComboBoxItem)typeproduit.SelectedItem).Content.ToString() == "Isolant")
{
EpIsolant.Visibility = Visibility.Visible;
EpIsolantLabel.Visibility = Visibility.Visible;
}
else
{
EpIsolant.Visibility = Visibility.Hidden;
EpIsolantLabel.Visibility = Visibility.Hidden;
}
}
As already said, you could consider things such changing Visibility or IsEnabled property of Button to hide/disable it.
But if you want to stick with your solution, you could take out the variable outside the method:
private TextBox _epIsolant;
Then you can assign it a object:
_epIsolant = new TextBox
{
Width = 100,
Height = 29,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Top,
Margin = new Thickness(209, 294, 0, 0)
};
and you can also check if it was created inside your method:
if(_epIsolant == null)
{
...
}

How to prevent vertical scroll bar to lap my stack panels wpf

I am wondering how could I prevent vertical scroll bar from lapping my stack panels.
I am working on small wpf app where customers can add articles(drinks) to a something like cart, and when user click on article its added to the right part of window in stack panel, this is how it looks a like:
But I have problem when I add more than lets say 5-6 items to my stack panel, than vertical scroll bar is appearing and this is what's happening (notice vertical scroll bar to the right) its laping "x1":
How could I prevent this guy? Is it possible to move content to the left or something like that without laping my items/articles ...
If the code of how I add items to stackPanel is needed, I will post it in a sec?
HERE IS MY FULL CODE ABOUT THIS PART:
public MyDrinksPanel(int id, int groupID, double price,double priceHappy, string text, int fontSize, int numberSize, int buttonWidth, int buttonHeight, int margin, Thickness border, byte[] image)
: base()
{
this.Width = buttonWidth+90;
this.Height = buttonHeight;
image.Source = GetimageFromByte(image);
ID = id;
groupID = groupID;
price = price;
priceHappy = priceHappy;
DugmePanel.HorizontalAlignment = HorizontalAlignment.Center;
DugmePanel.VerticalAlignment = VerticalAlignment.Center;
DugmePanel.Orientation = Orientation.Horizontal;
DugmePanel.MaxWidth = DugmePanel.Width = buttonWidth;
//DugmePanel.Height = 70;
DugmePanel.Height = DugmePanel.MaxHeight = this.Height;
BrushConverter MyBrush = new BrushConverter();
DugmePanel.Background = (Brush)MyBrush.ConvertFrom("#50000000");
_image.Width = 120;
_image.Height = buttonHeight;
_image.HorizontalAlignment = HorizontalAlignment.Left;
_image.VerticalAlignment = VerticalAlignment.Center;
BrushConverter MyBrush2 = new BrushConverter();
RightNumberPanel.HorizontalAlignment = HorizontalAlignment.Right;
RightNumberPanel.VerticalAlignment = VerticalAlignment.Center;
RightNumberPanel.Orientation = Orientation.Horizontal;
RightNumberPanel.Width = RightNumberPanel.MaxWidth = this.Width - DugmePanel.Width;
RightNumberPanel.Height = RightNumberPanel.MaxHeight = this.Height;
NumberLabel.FontFamily = Util.Font; //new System.Windows.Media.FontFamily("HelveticaNeueLTStd-Bd.otf#Helvetica Neue LT Std");
ArticleNameLabel.VerticalContentAlignment = VerticalAlignment.Center;
ArticleNameLabel.HorizontalContentAlignment = HorizontalAlignment.Left;
ArticleNameLabel.FontSize = fontSize;
ArticleNameLabel.Foreground = System.Windows.Media.Brushes.White;
ArticleNameLabel.MaxWidth = _image.Width+45; //- 3;
ArticleNameLabel.FontFamily = Util.Font;//new System.Windows.Media.FontFamily("HelveticaNeueLTStd-Bd.otf#Helvetica Neue LT Std");
NumberLabel.Height = NumberLabel.MaxHeight = this.Height;
NumberLabel.FontSize = numberSize;
NumberLabel.Margin = new Thickness(0, 0, 0, 0);
NumberLabel.VerticalAlignment = VerticalAlignment.Center;
NumberLabel.HorizontalAlignment = HorizontalAlignment.Right;
NumberLabel.HorizontalContentAlignment = HorizontalAlignment.Right;
NumberLabel.Foreground= System.Windows.Media.Brushes.White;
NumberLabel.FontWeight = FontWeights.Bold;
BrushConverter MyBrush3 = new BrushConverter();
NumberLabel.Background = (Brush)MyBrush3.ConvertFrom("#83D744");
NumberLabel.Foreground = new SolidColorBrush(Colors.Black);
ArticleNameLabel.Content = text;
NumberLabel.Content = "x1";
DugmePanel.Children.Add(image);
DugmePanel.Children.Add(ArticleNameLabel);
RightNumberPanel.Children.Add(NumberLabel);
Rectangle rct = new Rectangle();
rct.Fill = System.Windows.Media.Brushes.White;
rct.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
rct.Height = 2;
//rct.Width = 100;
_animations = new DoubleAnimation(numberSize, numberSize + 15, new Duration(new TimeSpan(0, 0, 0, 0, 300)));
_animations.AutoReverse = true;
this.Margin = border;
this.Orientation = Orientation.Horizontal;
StackPanel spNew = new StackPanel();
spNew.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
spNew.Orientation = System.Windows.Controls.Orientation.Horizontal;
spNew.Children.Add(DugmePanel);
spNew.Children.Add(RightNumberPanel);
StackPanel spNew2 = new StackPanel();
spNew2.Orientation = System.Windows.Controls.Orientation.Vertical;
spNew2.Children.Add(spNew);
this.Children.Add(spNew2);
}
I dont have a lot about XAML HERE:
This is only part:
<ScrollViewer x:Name="ScrollerOnTheRight" Margin="0,0,0,60" HorizontalScrollBarVisibility="Disabled" Grid.Row="1" Grid.Column="2" VerticalScrollBarVisibility="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<StackPanel Grid.Row="1" x:Name="stackRacun" Grid.Column="2"/>
</ScrollViewer>
Thanks guys,
Cheers

Popup Not Showing

On a tap event I would like to show a popup all within code behind, but my popup is not displaying?
void PopupDisplay_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
if (sender != null)
{
p = new Popup
{
Width = 480,
Height = 580,
HorizontalAlignment = System.Windows.HorizontalAlignment.Center,
VerticalAlignment = System.Windows.VerticalAlignment.Center
};
Border b = new Border();
b.BorderBrush = new SolidColorBrush(Colors.Gray);
b.BorderThickness = new Thickness(2);
b.Margin = new Thickness(10, 10, 10, 10);
p.Child = b;
p.IsOpen = true;
}
}
Think you're trying to Popup over a top-level control like a Pivot which is very buggy.
See Popup with Pivots
If it was a Grid, it would pop up without problem. To fix this you will have to add it to the same visual level as the Pivot like so:
<Grid x:Name="ContentPanel" Margin="0,0,0,0">
<phone:Pivot x:Name="MainDisplay">
<!-- more code -->
</phone:Pivot>
</Grid>
Then in your code-behind
// I made with a thickness of 100, so we can see the border better
Popup p;
p = new Popup
{
Width = 480,
Height = 580,
VerticalOffset = 0
};
Border b = new Border();
b.BorderBrush = new SolidColorBrush(Colors.Red);
b.BorderThickness = new Thickness(100);
b.Margin = new Thickness(10, 10, 10, 10);
b.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
b.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
p.Child = b;
// add it to the same level as the pivot to over ride pivot
this.ContentPanel.Children.Add(p);
p.IsOpen = true;

Cannot access dynamic controls

I have some trouble when i'm trying to click my dynamic controls in StackPanel.
I'm adding controls to Grid in this way...
void Opt()
{
TextBlock Title_1 = new TextBlock();
TextBlock Title_2 = new TextBlock();
CheckBox Kwota_exists = new CheckBox();
TextBox Title = new TextBox();
StackPanel Frame = new StackPanel();
Button OK = new Button();
Title_1.Text = "Dodaj kategorię";
Title_2.Text = "Aktywne kategorię";
Kwota_exists.Content = "Stała kwota?";
Title.Text = "Nazwa kategorii";
OK.Content = "Dodaj";
OK.IsEnabled = true;
OK.IsHitTestVisible = true;
OK.IsTabStop = true;
OK.ClickMode = ClickMode.Release;
Frame.IsHitTestVisible = true;
Kwota_exists.Checked +=Kwota_exists_Checked;
Title_1.FontSize = 50;
Title_2.FontSize = 50;
Title.FontSize = 20;
Frame.Height = 100;
Frame.Width = 400;
Title_1.Margin = new Thickness(0, 0, 0, 0);
Title_2.Margin = new Thickness(0, 220, 0, 0);
Frame.Margin = new Thickness(0, 70, 0, 0);
Frame.HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Left;
Frame.VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Top;
Frame.Orientation = Orientation.Horizontal;
Frame.Background = new SolidColorBrush(Windows.UI.Color.FromArgb(145, 56, 234, 21));
Frame.Children.Add(Kwota_exists);
Frame.Children.Add(Title);
Frame.Children.Add(OK);
GrdContent.Children.Add(Frame);
GrdContent.Children.Add(Title_1);
GrdContent.Children.Add(Title_2);
}
But when i'm trying to click button or check checkbox controls doesn't seem to response (unclickable).
Looks like i can't access them or i'm doing something wrong. I would be gradefull if someone explain me where i'm doing mistake.

Categories

Resources