There are 2 part for setting style of button.
The 1st is BackgroundProperty by Style.Setters. It's working well.
The 2nd is BackgroundProperty by Style.Triggers which is run by that Mouse is over a button. But, It's not working.
// the 1st BackgroundProperty by Style.Setters
Style style = new Style(typeof(Button));
style.Setters.Add(new Setter(Button.BackgroundProperty, imageSourceOn));
// the 2nd BackgroundPropert by Style.Triggers
Setter setter = new Setter();
setter.Property = Button.BackgroundProperty;
setter.Value = imageSourceOff;
Trigger trigger = new Trigger();
trigger.Property = IsMouseOverProperty;
trigger.Value = true;
trigger.Setters.Add(setter);
style.Triggers.Add(trigger);
Button button = new Button();
button.Margin = new Thickness(0, 5, 80, 5);
button.BorderThickness = new Thickness(0);
button.Name = name;
button.Click += handler;
button.VerticalContentAlignment = VerticalAlignment.Bottom;
// setting Style
button.Style = style;
return button;
Thanks Ed Plunkett.
I added ControlTemplate to override the control's background brush property.
Style style = new Style(typeof(Button));
style.Setters.Add(new Setter(Button.BackgroundProperty, imageSourceOn));
This is the ControlTemplate part what I add:
ControlTemplate template = new ControlTemplate(typeof(Button));
FrameworkElementFactory elemFactory = new FrameworkElementFactory(typeof(Border));
elemFactory.Name = "Border";
elemFactory.SetValue(Border.BackgroundProperty, new TemplateBindingExtension(Button.BackgroundProperty));
template.VisualTree = elemFactory;
elemFactory.AppendChild(new FrameworkElementFactory(typeof(ContentPresenter)));
And, It is trigger part.
Setter setter = new Setter();
setter.Property = Button.BackgroundProperty;
setter.Value = imageSourceOff;
Trigger trigger = new Trigger();
trigger.Property = IsMouseOverProperty;
trigger.Value = true;
trigger.Setters.Add(setter);
Finally, I set my ControlTemplate.
template.Triggers.Add(trigger);
setter = new Setter();
setter.Property = Button.TemplateProperty;
setter.Value = template;
style.Setters.Add(setter);
It works well.
Related
I am trying to read an "ini" file and to create multiple radiobuttons depending on the number of the lines of this file. The code used is the following:
private void CreateRadioButtons(string filePath)
{
StackPanel mainStackPanel = new StackPanel();
mainStackPanel.Orientation = Orientation.Vertical;
mainStackPanel.HorizontalAlignment = HorizontalAlignment.Stretch;
mainStackPanel.VerticalAlignment = VerticalAlignment.Stretch;
var lines = File.ReadAllLines(filePath).Where(l => !l.StartsWith(";"));
WrapPanel wrapPanel = new WrapPanel();
wrapPanel.Margin = new Thickness(30);
ScrollViewer scrollViewer = new ScrollViewer();
Style style = new Style(typeof(RadioButton));
style.Setters.Add(new Setter(RadioButton.BackgroundProperty, Brushes.Yellow));
style.Setters.Add(new Setter(RadioButton.BorderThicknessProperty, new Thickness(2)));
ControlTemplate controlTemplate = new ControlTemplate(typeof(RadioButton));
FrameworkElementFactory border = new FrameworkElementFactory(typeof(Border));
border.SetValue(Border.BorderThicknessProperty, new TemplateBindingExtension(BorderThicknessProperty));
border.SetValue(Border.BorderBrushProperty, new TemplateBindingExtension(BorderBrushProperty));
border.SetValue(Border.BackgroundProperty, Brushes.Transparent);
border.SetValue(Border.CornerRadiusProperty, new CornerRadius(20));
border.SetValue(BorderBrushProperty, new SolidColorBrush(Colors.Blue));
border.SetValue(Border.BackgroundProperty, Brushes.Transparent);
FrameworkElementFactory image = new FrameworkElementFactory(typeof(Image));
image.SetValue(Image.SourceProperty, new BitmapImage(new Uri("pack://application:,,,/Resources/image.jpg")));
FrameworkElementFactory textBlock = new FrameworkElementFactory(typeof(TextBlock));
textBlock.Name = "TextBlock";
textBlock.SetValue(TextBlock.TextProperty, "Text");
textBlock.SetValue(TextBlock.MarginProperty, new Thickness(5));
FrameworkElementFactory secondaryStack = new FrameworkElementFactory(typeof(StackPanel));
secondaryStack.SetValue(StackPanel.OrientationProperty, Orientation.Vertical);
secondaryStack.SetValue(StackPanel.MarginProperty, new Thickness(5, 10, 5, 0));
secondaryStack.AppendChild(image);
secondaryStack.AppendChild(textBlock);
border.AppendChild(secondaryStack);
controlTemplate.VisualTree = border;
style.Setters.Add(new Setter(Control.TemplateProperty, controlTemplate));
Trigger trigger = new Trigger() { Property = RadioButton.IsCheckedProperty, Value = false };
trigger.Setters.Add(new Setter(UIElement.OpacityProperty, 0.5));
style.Triggers.Add(trigger);
FrameworkElementFactory label = new FrameworkElementFactory(typeof(Label));
foreach (var line in lines)
{
RadioButton radioButton = new RadioButton();
radioButton.Style = style;
radioButton.Width = 135;
radioButton.Height = 125;
radioButton.Margin = new Thickness(15, 0, 0, 15);
radioButton.Content = border;
wrapPanel.Children.Add(radioButton);
}
This code is functioning at the moment. The problem comes when i try to implement textblocks with dynamic text: I just need the text inside the radiobutton to be equal to the string line. I have tried multiple ways but in the end I only encounter exceptions about windowspresentation (which I think mean that the elements are presented in the wrong way). How can I make textBlock dynamic?
I am creating a Button control using C# as mentioned below in the code. I have created the rounded border for the button style. I am not able to see any property to assign the Border in the button.
var button = new System.Windows.Controls.Button
{
Name = "BtnOk",
Content = "OK",
Height = 20,
Width = 60,
HorizontalAlignment = HorizontalAlignment.Center,
Background = Brushes.DarkGray,
Foreground = Brushes.WhiteSmoke,
Margin = new Thickness(0,0,0,5)
};
Border border = new Border();
border.CornerRadius = new CornerRadius(3);
How can I apply Border in button programatically?
a button cannot aplly a border. a border can decorate a button:
border.Child = button;
usually Buttons already have a Border inside their Template (ControlTemplate). that Border isn't easily accessible - there is no special property of Button class, but that border can be found in visual tree after template was loaded.
additionally that Border can be customized by default style if you put it in Button.Resources. change CorderRadius using Style.Setter:
var button = new System.Windows.Controls.Button
{
Name = "BtnOk",
Content = "OK",
Height = 20,
Width = 60,
HorizontalAlignment = HorizontalAlignment.Center,
Background = Brushes.DarkGray,
Foreground = Brushes.WhiteSmoke,
Margin = new Thickness(0, 0, 0, 5)
};
var style = new Style
{
TargetType = typeof(Border),
Setters = { new Setter { Property = Border.CornerRadiusProperty, Value = new CornerRadius(3) } }
};
button.Resources.Add(style.TargetType, style);
or using object/collection initializers:
var button = new System.Windows.Controls.Button
{
Name = "BtnOk",
Content = "OK",
Height = 20,
Width = 60,
HorizontalAlignment = HorizontalAlignment.Center,
Background = Brushes.DarkGray,
Foreground = Brushes.WhiteSmoke,
Margin = new Thickness(0, 0, 0, 5),
Resources =
{
{
typeof(Border), new Style
{
TargetType = typeof(Border),
Setters =
{
new Setter { Property = Border.CornerRadiusProperty, Value = new CornerRadius(13) }
}
}
}
}
};
if many buttons should have different CornerRadius, changing Button's Template can be a solution. Change template and set CornerRadius as attached dependency property, like shown in this post: Set a property of a nested element in an WPF style
There is indeed a Border element in the default ControlTemplate for the Button but the easiest way to set the CornerRadius property of it, without having to define a custom template, is to wait until the Button has been loaded and then get a reference to it. Try this:
var button = new System.Windows.Controls.Button
{
Name = "BtnOk",
Content = "OK",
Height = 20,
Width = 60,
HorizontalAlignment = HorizontalAlignment.Center,
Background = Brushes.DarkGray,
Foreground = Brushes.WhiteSmoke,
Margin = new Thickness(0, 0, 0, 5)
};
button.Loaded += (ss, ee) =>
{
Border border = button.Template.FindName("border", button) as Border;
if (border != null)
border.CornerRadius = new CornerRadius(3);
};
I have been able to do the above with the following code in my subclassed TabItem:
protected override void OnSelected(RoutedEventArgs e)
{
base.OnSelected(e);
if (this.StoryBoard == null)
{
ColorAnimation anim = new ColorAnimation(Colors.Transparent, Colors.AliceBlue, new Duration(TimeSpan.FromSeconds(1)))
{
AutoReverse = true,
RepeatBehavior = RepeatBehavior.Forever
};
Storyboard.SetTarget(anim, this);
Storyboard.SetTargetProperty(anim, new PropertyPath("Background.Color"));
Storyboard sb = new Storyboard();
sb.Children.Add(anim);
this.StoryBoard = sb;
}
VisualTree.FindParent<OMWTabControl>(this).Items.Cast<OMWTabItem>().ToList().ForEach(n =>
{
if (n.StoryBoard != null)
{
n.StoryBoard.Stop();
}
});
this.StoryBoard.Begin();
}
I know I am butchering the correct way to do this - I should be using DataTriggers I believe with Setters.
I have done extensive searching and it's all in XAML which is mostly intrepretable into C#, but not all.
Can someone point me to the "correct" way to do this in code behind?
Whenever you want to know about any methods, interfaces, classes, or just about anything about the .NET Framework, just go to MSDN. You could have gone to the Storyboard.TargetProperty Attached Property page on MSDN for a super quick answer to your question. From the linked page:
public StoryboardExample()
{
// Create a name scope for the page.
NameScope.SetNameScope(this, new NameScope());
this.WindowTitle = "Animate Properties using Storyboards";
StackPanel myStackPanel = new StackPanel();
myStackPanel.MinWidth = 500;
myStackPanel.Margin = new Thickness(30);
myStackPanel.HorizontalAlignment = HorizontalAlignment.Left;
TextBlock myTextBlock = new TextBlock();
myTextBlock.Text = "Storyboard Animation Example";
myStackPanel.Children.Add(myTextBlock);
//
// Create and animate the first button.
//
// Create a button.
Button myWidthAnimatedButton = new Button();
myWidthAnimatedButton.Height = 30;
myWidthAnimatedButton.Width = 200;
myWidthAnimatedButton.HorizontalAlignment = HorizontalAlignment.Left;
myWidthAnimatedButton.Content = "A Button";
// Set the Name of the button so that it can be referred
// to in the storyboard that's created later.
// The ID doesn't have to match the variable name;
// it can be any unique identifier.
myWidthAnimatedButton.Name = "myWidthAnimatedButton";
// Register the name with the page to which the button belongs.
this.RegisterName(myWidthAnimatedButton.Name, myWidthAnimatedButton);
// Create a DoubleAnimation to animate the width of the button.
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 200;
myDoubleAnimation.To = 300;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(3000));
// Configure the animation to target the button's Width property.
Storyboard.SetTargetName(myDoubleAnimation, myWidthAnimatedButton.Name);
Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Button.WidthProperty));
// Create a storyboard to contain the animation.
Storyboard myWidthAnimatedButtonStoryboard = new Storyboard();
myWidthAnimatedButtonStoryboard.Children.Add(myDoubleAnimation);
// Animate the button width when it's clicked.
myWidthAnimatedButton.Click += delegate(object sender, RoutedEventArgs args)
{
myWidthAnimatedButtonStoryboard.Begin(myWidthAnimatedButton);
};
myStackPanel.Children.Add(myWidthAnimatedButton);
//
// Create and animate the second button.
//
// Create a second button.
Button myColorAnimatedButton = new Button();
myColorAnimatedButton.Height = 30;
myColorAnimatedButton.Width = 200;
myColorAnimatedButton.HorizontalAlignment = HorizontalAlignment.Left;
myColorAnimatedButton.Content = "Another Button";
// Create a SolidColorBrush to paint the button's background.
SolidColorBrush myBackgroundBrush = new SolidColorBrush();
myBackgroundBrush.Color = Colors.Blue;
// Because a Brush isn't a FrameworkElement, it doesn't
// have a Name property to set. Instead, you just
// register a name for the SolidColorBrush with
// the page where it's used.
this.RegisterName("myAnimatedBrush", myBackgroundBrush);
// Use the brush to paint the background of the button.
myColorAnimatedButton.Background = myBackgroundBrush;
// Create a ColorAnimation to animate the button's background.
ColorAnimation myColorAnimation = new ColorAnimation();
myColorAnimation.From = Colors.Red;
myColorAnimation.To = Colors.Blue;
myColorAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(7000));
// Configure the animation to target the brush's Color property.
Storyboard.SetTargetName(myColorAnimation, "myAnimatedBrush");
Storyboard.SetTargetProperty(myColorAnimation, new PropertyPath(SolidColorBrush.ColorProperty));
// Create a storyboard to contain the animation.
Storyboard myColorAnimatedButtonStoryboard = new Storyboard();
myColorAnimatedButtonStoryboard.Children.Add(myColorAnimation);
// Animate the button background color when it's clicked.
myColorAnimatedButton.Click += delegate(object sender, RoutedEventArgs args)
{
myColorAnimatedButtonStoryboard.Begin(myColorAnimatedButton);
};
myStackPanel.Children.Add(myColorAnimatedButton);
this.Content = myStackPanel;
}
Please visit the linked page for further information.
I'm trying to set the following properties in the C# code behind of StackPanel that I need to add programmatically:
BorderThickness
BorderBrush
Any idea on how to set these programmatically?
I know this is a year later, but I have found an answer in case someone still needs it.
Here is a complete example
// Create a StackPanel and Add children
StackPanel myStackPanel = new StackPanel();
Border myBorder1 = new Border();
myBorder1.Background = Brushes.SkyBlue;
myBorder1.BorderBrush = Brushes.Black;
myBorder1.BorderThickness = new Thickness(1);
TextBlock txt1 = new TextBlock();
txt1.Foreground = Brushes.Black;
txt1.FontSize = 12;
txt1.Text = "Stacked Item #1";
myBorder1.Child = txt1;
Border myBorder2 = new Border();
myBorder2.Background = Brushes.CadetBlue;
myBorder2.Width = 400;
myBorder2.BorderBrush = Brushes.Black;
myBorder2.BorderThickness = new Thickness(1);
TextBlock txt2 = new TextBlock();
txt2.Foreground = Brushes.Black;
txt2.FontSize = 14;
txt2.Text = "Stacked Item #2";
myBorder2.Child = txt2;
// Add the Borders to the StackPanel Children Collection
myStackPanel.Children.Add(myBorder1);
myStackPanel.Children.Add(myBorder2);
mainWindow.Content = myStackPanel;
The StackPanel does not have a BorderThickness or BorderBrush properties. Only Background. If you want to set those, you would need to wrap the StackPanel in a Border control:
<Border x:Name="StackBorder">
<StackPanel>
</Border>
You can then call:
StackBorder.BorderThickness = new Thickness(1);
StackBorder.BorderBrush = new Windows.UI.Xaml.Media.SolidColorBrush(Windows.UI.Colors.Red);
You cannot set border properties on the StackPanel object itself. You place the StackPanel object inside a Border object and set the BorderThickness and BorderBrush properties on the Border object with something like:
myBorder.BorderBrush = Brushes.Black;
myBorder.BorderThickness = new Thickness(1);
I have two TextBoxes and I want to bind between their Visibility property in run time,
The binding works when I add the TextBoxes by Xaml but doesn't work when I add them programmatically,
Any help !!
public partial class Window1 : Window
{
TextBox txt1 = new TextBox();
TextBox txt2 = new TextBox();
public Window1()
{
InitializeComponent();
txt1.Name = "txt1";
txt1.Margin= new Thickness(30,0,128,0);
txt1.VerticalAlignment = VerticalAlignment.Top;
txt2.Name = "txt2";
txt2.Margin = new Thickness(30, 32, 128, 0);
txt2.VerticalAlignment = VerticalAlignment.Top;
Binding binding = new Binding();
binding.ElementName = "txt1";
binding.Path = new PropertyPath(TextBox.VisibilityProperty);
BindingOperations.SetBinding(txt2, TextBox.VisibilityProperty, binding);
grid.Children.Add(txt1);
grid.Children.Add(txt2);
}
}
Thanks in advance
UPDATED
Instead of setting the ElementName property, just set the Source property for the Binding to the Element object you wish to bind to.
TextBox txt1 = new TextBox();
TextBox txt2 = new TextBox();
public Window1()
{
InitializeComponent();
txt1.Name = "txt1";
txt1.Margin = new Thickness(30, 0, 128, 0);
txt1.VerticalAlignment = VerticalAlignment.Top;
txt1.Visibility = Visibility.Visible;
txt2.Name = "txt2";
txt2.Margin = new Thickness(30, 32, 128, 0);
txt2.VerticalAlignment = VerticalAlignment.Top;
Binding binding = new Binding();
binding.Source = txt1; // set the source object instead of ElementName
binding.Path = new PropertyPath(TextBox.VisibilityProperty);
BindingOperations.SetBinding(txt2, TextBox.VisibilityProperty, binding);
grid.Children.Add(txt1);
grid.Children.Add(txt2);
}