I want create a ToggleButton with round corners by using my CornerRadius property. As you can see in the code below, i already added a cornerRadius property to my xaml ToggleButton to pass a radius value. But i can't find a way to use this value in c# to create a ToggleButton with round corners.
C#
public static readonly DependencyProperty CornerRadiusProperty =
DependencyProperty.Register("CornerRadius", typeof(int), typeof(MyToggleButton),
new PropertyMetadata(0)); //Default CornerRadius = 0
public int CornerRadius
{
get { return (int)GetValue(CornerRadiusProperty); }
set { SetValue(CornerRadiusProperty, value); }
}
XAML
<custom:MyToggleButton Height="25" Content="Test" CornerRadius="15" />
So how can i create a toggleButton with round corners by using my property "CornerRadius"?
Would be great if someone could help me.
I wouldn't create a new control just in order to make it round - that's what templates are for and that's what makes WPF so great! You could simply define a new template for the ToggleButton.
If you insist on inheriting your own control, you'll need to define for it a new default style that will also include a control template that will have a border that uses your CornerRadius property. You can base your new template on the default control template for ToggleButton.
Related
I have a situation where I need to tab using TabKey from one control to another. The condition is that the focus should never go to control that does not have user inputs so only Text, ComboBox, List DatePicker but somehow the focus after 3 controls get the Focus to go to a dashed line Rectangle (Could be of a Grid, StackPanel, I have not been able to findout) around the control groups before it gets into the control. I have searched very thoroughly in Google and stack over flow for a solution but none seem to work.
Various solutions I tried:
1) Here I set FocusVisualStyle property to null right at start up for Grid and StackPanels. Created a new class:
<StackPanel views:FocusVisualTreeChanger.IsChanged="True" Name="parentStackPanel" Orientation="Vertical" Style="{DynamicResource key1}" FocusVisualStyle="{x:Null}">
public class FocusVisualTreeChanger
{
public static bool GetIsChanged(DependencyObject obj)
{
return (bool)obj.GetValue(IsChangedProperty);
}
public static void SetIsChanged(DependencyObject obj, bool value)
{
obj.SetValue(IsChangedProperty, value);
}
public static readonly DependencyProperty IsChangedProperty =
DependencyProperty.RegisterAttached("IsChanged", typeof(bool), typeof(FocusVisualTreeChanger), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits, IsChangedCallback));
private static void IsChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (true.Equals(e.NewValue))
{
FrameworkContentElement contentElement = d as FrameworkContentElement;
if (contentElement != null)
{
contentElement.FocusVisualStyle = null;
return;
}
FrameworkElement element = d as FrameworkElement;
if (element != null)
{
element.FocusVisualStyle = null;
}
}
}
}
Did not work.
I tried setting FocusVisualStyle property to null for only Grid and StackPanel seems to go through the codebehind if I put a break point but the focus rectangle does not go away:
<Grid Name="AppointmentGrid" Style="{DynamicResource key2}" FocusVisualStyle="{x:Null}">
Style style = new Style { TargetType = typeof(Grid) };
style.Setters.Add(new Setter(Grid.FocusVisualStyleProperty, null));
style.Setters.Add(new Setter(Grid.FocusableProperty, false));
Application.Current.Resources["key2"] = style;
Application.Current.Resources["key3"] = style;
Application.Current.Resources["key4"] = style;
Style style1 = new Style { TargetType = typeof(StackPanel) };
style1.Setters.Add(new Setter(StackPanel.FocusVisualStyleProperty, null));
style1.Setters.Add(new Setter(StackPanel.FocusableProperty, false));
Application.Current.Resources["key1"] = style1;
Can anyone please help me out with a solution that I have not already tried. None in stackoverflow solutions seem to work. I also set Focusable=false just incase but that doesn't seem to help either.
I also read:
Remove focus rectangle on a UserControl
WPF Control remove focus and hover effect (FocusVisualStyle?!)
WPF: Remove dotted border around focused item in styled listbox
This is what I think I am stuck at. A comment I found in one of the search sites.
That's a great way to change the default value of a DP, but it will not help in situations where a control's style explicitly changes the property value. Unfortunately, FocusVisualStyle is one such property. More specifically, styles for controls like Button, ComboBox, ListBox, etc. tend to explicitly contain a Setter for the FocusVisualStyle property. This setter will override the default value that you establish by overriding the metadata.
Can someone suggest a solution that will work in my case. I have a User control
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:csla="http://schemas.lhotka.net/4.2.0/xaml"
xmlns:input="clr-
FocusVisualStyle="{x:Null}"
Focusable="False"
xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit"
mc:Ignorable="d" d:DesignWidth="948"
IsTabStop="False"
TabIndex="-1">
<StackPanel views:FocusVisualTreeChanger.IsChanged="True" Name="parentStackPanel" Orientation="Vertical" Style="{DynamicResource key1}" FocusVisualStyle="{x:Null}"><Grid Name="AppointmentGrid" Style="{DynamicResource key2}" FocusVisualStyle="{x:Null}">
Thanks
Dhiren
For a TextBlock in XAML, you can do the following inside a DataTemplate:
<TextBlock Text="myTextBlock Text" VerticalAlignment="Center" Margin="0,0,5,0"
ScrollViewer.CanContentScroll="True" ScrollViewer.HorizontalScrollBarVisibility="Visible"/>
But when I try to set ScrollViewer.HorizonalScrollBarVisibility, it doesn't seem to do anything.
DataTemplate textBlockTemplate = new DataTemplate();
FrameworkElementFactory textBlockElement = new FrameworkElementFactory(typeof(TextBlock));
Binding c1Binding = new Binding("myBindingValue") { Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged };
textBlockElement.SetBinding(TextBlock.TextProperty, c1Binding);
textBlockElement.SetValue(TextBlock.TextWrappingProperty, TextWrapping.Wrap);
textBlockElement.SetValue(TextBlock.HeightProperty, System.Convert.ToDouble(23));
textBlockElement.SetValue(ScrollViewer.CanContentScrollProperty, true);
textBlockElement.SetValue(ScrollViewer.HorizontalScrollBarVisibilityProperty, ScrollBarVisibility.Visible);
textBlockTemplate.VisualTree = textBlockElement;
templateColumn.CellTemplate = textBlockTemplate;
myDataGrid.Columns.Add(templateColumn);
I am trying to make a DataGrid Column that has a TextBlock that shows one line of text, but allows you to scroll up/down to see the rest of the textblock.
TextBlock doesn't have a ScrollViewer contained in it to set scrolling behavior on. You need to wrap it in a ScrollViewer on which you can set whatever you want. Contrast this to a ListBox, which does contain a ScrollViewer in its ControlTemplate so can take advantage of the attached properties.
I have a TextBlock control in my view, its Width depends on the Text property.
I'm looking for some way to bind the TextBlocks Width to a property in my model,which will work as follows:
The setting of the Width must be done automatically based on Text
In my button click I would like to retrieve the Width
I've tried the code below, but it keeps the Width as 0 if I don't explicitly set it in the constructor of the view model.Tried Mode=OneWayToSource and Mode=OneWay but it made no difference, any suggestions?
View:
<Grid>
<TextBlock Text="Some text" Width="{Binding TextWidth,Mode=OneWayToSource}" />
<Button Content="Show Width" Height="30" Width="90" Command="{Binding ShowTextWidth}" />
</Grid>
View model:
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private DelegateCommand<object> showTextWidth;
public DelegateCommand<object> ShowTextWidth
{
get { return showTextWidth; }
set { showTextWidth = value; }
}
private double textWidth;
public double TextWidth
{
get { return textWidth; }
set
{
textWidth = value;
OnPropertyChanged("TextWidth");
}
}
public ViewModel()
{
//If I explicitly specify the width it works:
//TextWidth = 100;
ShowTextWidth = new DelegateCommand<object>(ShowWidth);
}
private void ShowWidth(object parameter)
{
MessageBox.Show(TextWidth.ToString());
}
}
Ended up creating an attached behavior by Maleak which was inspired by Kent Boogaarts Pushing read-only GUI properties back into ViewModel, can't believe it's so complicated to push the value of ActualWidth into the view model!
Width is a DependencyProperty on TextBlock. In this case it's a Target for Binding and TextWidth is your source for Binding. OneWayToSource seems like the way to go, you are setting TextWidth to 100 in the ViewModel which does not propogate to Width on TextBlock because it's OneWayToSource yes correct, Width (Target) is then setting TextWidth (Source) to Double.NaN because of OneWayToSource and that's why you're seeing 0...
ActualWidth should work like sa_ddam213 said but also consider that your TextBlock doesn't grow in Width (ActualWidth) when the Text changes because it is spanning the total width of your Grid layout. Either put it in a ColumnDefinition with Width set to Auto or make your HorizontalAlignment Left to see the ActualWidth change when the Text changes.
I have made some changes to your source code. Consider using CommandParameter on your button? Check out the link...
WpfApplication10.zip
you dont really need to set the Width if you choose a layout panel wich can handle this for you.
eg. a columndefinition with width=auto grows with your text
To set the Width depending on its containing Text you could bind the Width-Property to the Text-Property and use a converter like so:
<TextBlock Width="{Binding RelativeSource={RelativeSource Self}, Path=Text, Converter={StaticResource TextToWidth}}"
Your converter could look like:
TextBlock tb = new TextBlock();
tb.Text = value.ToString();
tb.Measure(new Size(int.MaxValue, 20)); //20 if there shouldnt be a linebreak
return tb.DesiredSize.Width;
here is the XAML...
<Canvas Name="myCanvas">
<TextBlock Name="myBlock" FontFamily="Arial Black" FontSize="100" Foreground="Red" Text="R" Height="105" Width="96" Canvas.Left="61" Canvas.Top="80" /
</Canvas>
I have a partial class that extends a userControl.
public partial class Card : UserControl
I also have a test form that uses this control like this,
public formTest()
{
InitializeComponent();
Card1.drawText();
myCanvas.Children.Add(Card1); //myCanvas is defined in XAML
}
Card Card1 = new Card();
How do add an instance of TextBlock to myCanvas when TextBlock is inside my UserControl? So lets say,
public partial class Card : UserControl
{
private TextBlock txtBlock = new TextBlock();
public Card()
{
txtBlock.Text = "Test";
txtBlock.Foreground = brushFill;
}
public void drawText()
{
//uhhh idk
}
}
In general I don't understand how to get anything to display without defining it in the XAML then adding properties via code. Like this I create an instance of TextBlock, give it some properties... then I'm not sure.
Any help is appreciated. I also know I should be using a User Control but I don't know why?
Your UserControl should also have a XAML file associated, and the TextBlock should be inside that XAML.
The other option would be Card : Control (not UserControl) and then you would need a template.
In neither coase can/should you try to add a TextBlock from inside a Control to myCanvas.
Seems you ought to read up on WPF UserControls and Custom Controls.
If you just want to create a simple TextBlock and add it to the canvas, you'll want to do something like this:
TextBlock textBlock = new TextBlock();
textBlock.Text = "Text";
myCanvas.Children.Add(textBlock);
Then you can manipulate everything you have added to the Canvas via methods in Canvas.Children.
I have a reusable user control with a dependency property which sets the color of a rectangle. The property uses Brush as type.
The data binding works fine, however I would like to add a fallback and null value when the binding has errors or its value is not specified.
Here is my XAML:
<Rectangle Fill="{Binding Path=UnderLineColor, ElementName=Header,
FallbackValue=LightGrey, TargetNullValue=LightGrey}"
Height="2"
Margin="0,2"
Grid.Row="1"
Grid.ColumnSpan="2" />
And the code of the UnderLineColor DP:
public Brush UnderLineColor
{
get { return (Brush)GetValue(UnderLineColorProperty); }
set { SetValue(UnderLineColorProperty, value); }
}
public static readonly DependencyProperty UnderLineColorProperty =
DependencyProperty.Register("UnderLineColor", typeof(Brush), typeof(SectionHeader), null);
The issue is that SL doesn't seem to accept the fallback and nullvalue I specify.
What value should I write into these properties to make it work? Or should I use a ValueConverter instead of this approach?
Edit:
Top tip for today: Grey != Gray. Issue is fixed now. :)