Blink tab custom header - c#

I have been searching but I cant find much, I wanna make any of my dinamic tab headers background blink/flash when I call them to flash. I found this solution but I am kinda newbiew to binding and triggers on wpf so I couldnt do it.
The solution I found is this (Blink tab header on receiving event).
I will send some parts of my code below.
<TabControl x:Name="tabControlBTC" MouseLeftButtonDown="tabControlBTC_MouseLeftButtonDown" MouseRightButtonDown="tabControlBTC_MouseRightButtonDown" MouseDoubleClick="tabControlBTC_MouseDoubleClick"
TabStripPlacement="Left" Grid.Row="1" Grid.ColumnSpan="2" SelectionChanged="tabControlBTC_SelectionChanged">
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Width" Value="240"/>
<Setter Property="Height" Value="40"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border Width="auto" Name="Border" Margin="3,0,0,0" CornerRadius="0" SnapsToDevicePixels="True">
<ContentPresenter VerticalAlignment="Center" ContentSource="Header" Margin="12,2,12,2"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True" SourceName="Border">
<Setter TargetName="Border" Property="Background" Value="#EDF5FA" />
<Setter TargetName="Border" Property="BorderThickness" Value="4, 0, 0, 0"/>
<Setter TargetName="Border" Property="BorderBrush" Value="DarkGray"/>
<Setter TargetName="Border" Property="Margin" Value="3,0,0,0"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Black"/>
<Setter TargetName="Border" Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#DAE9F3" Offset="0.432" />
<GradientStop Color="#DAE9F3" Offset="0.433" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter TargetName="Border" Property="BorderThickness" Value="0"/>
<Setter TargetName="Border" Property="BorderBrush" Value="DarkGray"/>
<Setter TargetName="Border" Property="Margin" Value="0"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.ItemContainerStyle>
<TabControl.Template>
<ControlTemplate TargetType="TabControl">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ScrollViewer HorizontalScrollBarVisibility="Disabled" Background="#F4F4F5" VerticalScrollBarVisibility="Hidden" FlowDirection="LeftToRight">
<TabPanel x:Name="HeaderPanel" Panel.ZIndex ="0" KeyboardNavigation.TabIndex="1" IsItemsHost="true"/>
</ScrollViewer>
<ContentPresenter x:Name="PART_SelectedContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" ContentSource="SelectedContent" Grid.Column="1"/>
</Grid>
</ControlTemplate>
</TabControl.Template>
And how I create my tabitems headers dynamically.
UserControltest1 NewUserControlPage = new UserControltest1(contactNumber, username, jsonSellorBuy, 2);
newTab = new TabItem();
newTab.TabIndex = tabControlBTC.Items.Count + 1;
newTab.Name = "tab" + contactNumber;
PathGeometry CircleGeometry = new PathGeometry();
CircleGeometry.FillRule = FillRule.Nonzero;
PathFigureCollectionConverter pfcc = new PathFigureCollectionConverter();
CircleGeometry.Figures = (PathFigureCollection)pfcc.ConvertFrom("M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z");
System.Windows.Shapes.Path PathCirle = new System.Windows.Shapes.Path();
PathCirle.Fill = randomColor2();
PathCirle.Data = CircleGeometry;
var CanvasCirle = new Canvas() { Width = 24, Height = 24 };
TextBlock textBlockCircle = new TextBlock();
textBlockCircle.Text = username[0].ToString().ToUpper();
textBlockCircle.Foreground = new SolidColorBrush(Colors.Black);
textBlockCircle.Margin = new Thickness(0,3,0,3);
textBlockCircle.FontWeight = FontWeights.DemiBold;
textBlockCircle.TextAlignment = TextAlignment.Center;
textBlockCircle.Width = CanvasCirle.Width;
textBlockCircle.HorizontalAlignment = HorizontalAlignment.Center;
CanvasCirle.Children.Add(PathCirle);
CanvasCirle.Children.Add(textBlockCircle);
var viewBoxCircle = new Viewbox() { Width = 32, Height = 32, Margin = new Thickness(0, 0, 5, 0) };
viewBoxCircle.Child = CanvasCirle;
var stackPanel = new StackPanel() { Orientation = Orientation.Horizontal, Margin = new Thickness(-6, 0, 0, 0) };
var Buttoncircle = new Button() { Background = Brushes.Transparent, Margin = new Thickness(60, 0, 0, 0), BorderThickness = new Thickness(0) };
PathGeometry ButtonGeometry = new PathGeometry();
ButtonGeometry.FillRule = FillRule.Nonzero;
PathFigureCollectionConverter pfccc = new PathFigureCollectionConverter();
ButtonGeometry.Figures = (PathFigureCollection)pfccc.ConvertFrom("M13.46,12L19,17.54V19H17.54L12,13.46L6.46,19H5V17.54L10.54,12L5,6.46V5H6.46L12,10.54L17.54,5H19V6.46L13.46,12Z");
System.Windows.Shapes.Path PathCirleButton = new System.Windows.Shapes.Path();
PathCirleButton.Fill = Brushes.Black;
PathCirleButton.Data = ButtonGeometry;
Buttoncircle.Name = $"tab{contactNumber}";
var CanvasCirleButton = new Canvas() { Width = 24, Height = 24 };
CanvasCirleButton.Children.Add(PathCirleButton);
var viewBoxCircleButton = new Viewbox() { Width = 18};
viewBoxCircleButton.Child = CanvasCirleButton;
Buttoncircle.Content = viewBoxCircleButton;
Buttoncircle.Click += (s, e) => { Image_MouseDown(Buttoncircle); };
var stack = new StackPanel() { VerticalAlignment = VerticalAlignment.Top, Margin = new Thickness(0, 0, 0, 0) };
stack.Children.Add(new TextBlock() { Text = username, FontSize = 15 });
stack.Children.Add(new TextBlock() { Text = $"Trade #{contactNumber}", FontSize = 11 });
stackPanel.Children.Add(viewBoxCircle);
stackPanel.Children.Add(stack);
stackPanel.Children.Add(Buttoncircle);
newTab.Content = NewUserControlPage;
newTab.Header = stackPanel;
tabControlBTC.Items.Add(newTab);
tabControlBTC.SelectedItem = NewUserControlPage;

Your TabItem header is not just Text. it will be a Stackpanel contains other controls. Soi will simply animate the ContentControl.Opacity as shown below.
<Style x:Key="FlashingHeader" TargetType="TabItem">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<!--Make The Header -->
<ContentControl x:Name="header" Content="{Binding}" />
<!--Make The Background Flash-->
<DataTemplate.Triggers>
<Trigger Property="Visibility" Value="Visible">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="header"
Storyboard.TargetProperty="(ContentControl.Opacity)"
From="1" To="0" Duration="0:0:1" AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>

You just added one TabItem to the TabControl. Add one or more items into TabControl to see IsMouseOver and IsSelected triggers from the style. The single item in the TabControl will be selected already. You cannot see the visual effects.

Related

Changing mouse over Foreground color of controls inside a Button in code behind

I've got this bit of XAML code. What it does is override the style of a button when mousing over. Here I use Green and PaleGreen for the sake of simplicity.
<Style TargetType="Button" x:Key="someNameHere">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="Green" BorderThickness="2,0,0,0">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="PaleGreen"/>
<Setter Property="Foreground" Value="Black"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Green"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
This works on both a standard button and more exotic ones, like so:
<Button Name="Standard" Content="Test" Style="{DynamicResource someNameHere}"/>
<Button Name="Exotic" Style="{DynamicResource someNameHere}">
<TextBlock Text="Test"/>
</Button>
<Button Name="MoreExotic" Style="{DynamicResource someNameHere}">
<Grid>
<TextBlock Text="Test"/>
</Grid>
</Button>
I want to do the same thing in code behind, on a custom button class. This is the code I have this far:
public class FlatButton : Button
{
public FlatButton() : base()
{
BorderThickness = new Thickness(2, 0, 0, 0);
SetStyle();
}
private void SetStyle()
{
Background = Brushes.PaleGreen;
Foreground = Brushes.Black;
BorderBrush = Brushes.Green;
Style style = new Style(typeof(Button), Style);
ControlTemplate template = new ControlTemplate(typeof(Button));
FrameworkElementFactory border = new FrameworkElementFactory(typeof(Border));
border.SetValue(Border.BackgroundProperty, new TemplateBindingExtension(Button.BackgroundProperty));
border.SetValue(Border.BorderBrushProperty, BorderBrush);
border.SetValue(Border.BorderThicknessProperty, BorderThickness);
border.Name = "someNameHere";
template.VisualTree = border;
FrameworkElementFactory content = new FrameworkElementFactory(typeof(ContentPresenter));
content.SetValue(Border.VerticalAlignmentProperty, System.Windows.VerticalAlignment.Center);
content.SetValue(Border.HorizontalAlignmentProperty, System.Windows.HorizontalAlignment.Center);
border.AppendChild(content);
Trigger trigger = new Trigger()
{
Property = Button.IsMouseOverProperty,
Value = true
};
trigger.Setters.Add(new Setter()
{
TargetName = "someNameHere",
Property = Button.BackgroundProperty,
Value = Brushes.Green
});
trigger.Setters.Add(new Setter()
{
TargetName = "someNameHere",
Property = Button.ForegroundProperty,
Value = Brushes.White
});
template.Triggers.Add(trigger);
Setter setter = new Setter()
{
Property = Button.TemplateProperty,
Value = template
};
style.Setters.Add(setter);
Style = style;
}
And applying it to a similar set of buttons:
<local:FlatButton x:Name="Standard" Content="Test"/>
<local:FlatButton x:Name="Exotic">
<TextBlock Text="Test"/>
</local:FlatButton>
<local:FlatButton x:Name="MoreExotic">
<Grid>
<TextBlock Text="Test"/>
</Grid>
</local:FlatButton>
The problem is this works fine on the "standard" button, but it doesn't change the Foreground color of the elements inside the "exotic" buttons like the XAML version does, and I haven't been able to find a solution so far.
So does anyone know how do I set the Foreground color of my content in code?
The three use cases I'm interested in are plaintext, TextBlock, and TextBlock inside a container like a Grid or StackPanel.
The Style that you are creating programmatically is not equivalent to the one you have defined in the XAML markup. This is:
private void SetStyle()
{
Style style = new Style(typeof(Button), Style);
ControlTemplate template = new ControlTemplate(typeof(Button));
FrameworkElementFactory border = new FrameworkElementFactory(typeof(Border));
border.SetValue(Border.BackgroundProperty, new TemplateBindingExtension(Button.BackgroundProperty));
border.SetValue(Border.BorderBrushProperty, Brushes.Green);
border.SetValue(Border.BorderThicknessProperty, new Thickness(2, 0, 0, 0));
template.VisualTree = border;
FrameworkElementFactory content = new FrameworkElementFactory(typeof(ContentPresenter));
content.SetValue(Border.VerticalAlignmentProperty, System.Windows.VerticalAlignment.Center);
content.SetValue(Border.HorizontalAlignmentProperty, System.Windows.HorizontalAlignment.Center);
border.AppendChild(content);
style.Setters.Add(new Setter()
{
Property = Button.BackgroundProperty,
Value = Brushes.PaleGreen
});
style.Setters.Add(new Setter()
{
Property = Button.ForegroundProperty,
Value = Brushes.Black
});
Trigger trigger = new Trigger()
{
Property = Button.IsMouseOverProperty,
Value = true
};
trigger.Setters.Add(new Setter()
{
Property = Button.BackgroundProperty,
Value = Brushes.Green
});
trigger.Setters.Add(new Setter()
{
Property = TextBlock.ForegroundProperty,
Value = Brushes.White
});
template.Triggers.Add(trigger);
Setter setter = new Setter()
{
Property = Button.TemplateProperty,
Value = template
};
style.Setters.Add(setter);
Style = style;
}

Change Class-Binded Shadow Colour WPF

I was looking on how to replicate a Google button's shadow on hover effect in my WPF document and came across this: https://stackoverflow.com/a/53031057/12299798, which answers my problem exactly, but the only issue I have is that I normally do all the frontend things in XAML and so I am not quite experienced in the styling in C#. My problem is that I want to 'Bind' my foreground colour to the shadow colour, this is because in the code it only sets it to a greyish colour which would mean I would have to do a whole other class for each colour that I want to set it for. Here is my code now:
MainWindow.xaml:
<Button Content="shadow">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="local:UI.Elevation" Value="10"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="local:UI.Elevation" Value="0"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
UI.cs:
public static class UI
{
public static readonly DependencyProperty ElevationProperty = DependencyProperty.RegisterAttached("Elevation", typeof(double), typeof(UI), new FrameworkPropertyMetadata(default(double), FrameworkPropertyMetadataOptions.AffectsRender, null, OnRedElevationChanged));
public static double GetElevation(this UIElement element) => element.GetValue(ElevationProperty) as double? ?? default;
public static void SetElevation(this UIElement element, double elevation) => element.SetValue(ElevationProperty, elevation);
private static object OnRedElevationChanged(DependencyObject d, object value)
{
if (d is UIElement element && value is double elevation)
if (elevation == 0)
element.Effect = null;
else
{
Effect e = CreateElevation(elevation, element.Effect);
if (e != null)
element.Effect = e;
}
return value;
}
private static Effect CreateElevation(double elevation, Effect source)
{
void MixShadows(DropShadowEffect nearest, DropShadowEffect matched, double balance)
{
matched.BlurRadius = matched.BlurRadius * (1 - balance) + nearest.BlurRadius * balance;
matched.ShadowDepth = matched.ShadowDepth * (1 - balance) + nearest.ShadowDepth * balance;
}
DropShadowEffect[] shadows = new DropShadowEffect[]
{
new DropShadowEffect()
{
BlurRadius = 5,
ShadowDepth = 1
},
new DropShadowEffect()
{
BlurRadius = 8,
ShadowDepth = 1.5
},
new DropShadowEffect()
{
BlurRadius = 14,
ShadowDepth = 4.5
},
new DropShadowEffect()
{
BlurRadius = 25,
ShadowDepth = 8
},
new DropShadowEffect()
{
BlurRadius = 35,
ShadowDepth = 13
}
};
elevation = Math.Max(0, elevation / 12 * shadows.Length - 1);
int prevIndex = (int)Math.Floor(elevation), index = (int)elevation, nextIndex = (int)Math.Ceiling(elevation);
double approx = elevation - index;
DropShadowEffect shadow = shadows[index];
if (approx != 0)
MixShadows(approx < 0 ? shadows[prevIndex] : shadows[nextIndex], shadow, Math.Abs(approx));
bool modify = false;
if (source is DropShadowEffect sourceShadow)
{
sourceShadow.BlurRadius = shadow.BlurRadius;
sourceShadow.ShadowDepth = shadow.ShadowDepth;
shadow = sourceShadow;
modify = true;
}
shadow.Direction = 270;
shadow.Color = Colors.Red;
shadow.Opacity = .42;
shadow.RenderingBias = RenderingBias.Performance;
return modify ? null : shadow;
}
}
And to get what I want in XAML I would do something like this:
<Button Content="shadow">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="local:UI.Elevation" Value="10"/>
<Setter Property="local:UI.Elevation.Foreground" Value="Blue"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="local:UI.Elevation" Value="0"/>
<Setter Property="local:UI.Elevation.Foreground" Value="Blue"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
But I don't quite know how to link up the local:UI.Elevation.Foreground to change the shadow colour, I would have to change this line here from UI.cs: shadow.Color = Colors.Red; and bind it to the Elevation.Foreground, but I am having difficulties. Can anyone help?
All you need to do is updated the UI class with a new attached property named something like Color of type Color and give it a default color you like.
Then, in its OnColorChanged handler, call OnElevationChanged so that the shadow gets recreated.
#region Color (Attached Property)
public static readonly DependencyProperty ColorProperty =
DependencyProperty.RegisterAttached(
"Color",
typeof(Color),
typeof(UI),
new PropertyMetadata(Colors.Black, OnColorChanged));
public static Color GetColor(DependencyObject obj)
{
return (Color)obj.GetValue(ColorProperty);
}
public static void SetColor(DependencyObject obj, Color value)
{
obj.SetValue(ColorProperty, value);
}
private static void OnColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
OnElevationChanged(d, GetElevation((UIElement)d));
}
#endregion
In the CreateElevation method, add a new parameter for the color, so you can set it.
private static Effect CreateElevation(double elevation, Effect source, Color color)
{
...
shadow.Color = color;
...
}
Finally, in OnElevationChanged update it so it to call GetColor so it can pass in the new Color property.
private static object OnElevationChanged(DependencyObject d, object value)
{
if (d is UIElement element && value is double elevation)
if (elevation == 0)
element.Effect = null;
else
{
Effect e = CreateElevation(elevation, element.Effect, GetColor(element));
if (e != null)
element.Effect = e;
}
return value;
}
Example XAML
<Button
Width="100"
Height="20"
Content="shadow">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="local:UI.Elevation" Value="10" />
<Setter Property="local:UI.Color" Value="Blue" />
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="local:UI.Elevation" Value="5" />
<Setter Property="local:UI.Color" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
NOTE: There is some refactoring you could do to make all this cleaner, but hopefully this will get your started.

How to "expand" RichTextBox Paragraph's background color?

As you can see below, there are white margins from both sides, how to expand the gray background horizontally, so it will cover the TextBox from edge to edge?
<RichTextBox x:Name="logTextBox" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Auto" IsReadOnly="True" FontSize="12" Margin="10,165,10,10" >
<RichTextBox.Resources>
<Style TargetType="{x:Type Paragraph}">
<Setter Property="Margin" Value="0"/>
</Style>
<Style TargetType="ScrollViewer">
<Setter Property="MaxWidth" Value="480" />
</Style>
</RichTextBox.Resources>
</RichTextBox>
Usage:
public void AddLog(string log)
{
Run run = new Run(log);
Paragraph paragraph = new Paragraph(run);
paragraph.Background = new SolidColorBrush(Colors.Gray);
var numberOfBlocks = logTextBox.Document.Blocks.Count;
const int MaxNumberOfBlocks = 100;
if (numberOfBlocks > MaxNumberOfBlocks)
{
logTextBox.Document.Blocks.Remove(logTextBox.Document.Blocks.FirstBlock);
}
logTextBox.Document.Blocks.Add(paragraph);
logTextBox.ScrollToEnd();
}
Set the PagePadding property of the FlowDocument to 0 after the RichTextBox has been loaded:
public void AddLog(string log)
{
Run run = new Run(log);
Paragraph paragraph = new Paragraph(run);
paragraph.Background = new SolidColorBrush(Colors.Gray);
var numberOfBlocks = logTextBox.Document.Blocks.Count;
const int MaxNumberOfBlocks = 100;
if (numberOfBlocks > MaxNumberOfBlocks)
{
logTextBox.Document.Blocks.Remove(logTextBox.Document.Blocks.FirstBlock);
}
logTextBox.Document.Blocks.Add(paragraph);
logTextBox.Document.PagePadding = new Thickness(0); //<--
logTextBox.ScrollToEnd();
}

Expander button is not working properly in my wpf datagrid

Expander button is not working properly in my wpf datagrid. I am using the following template for expander button.
<!-- MouseOver, Pressed behaviours-->
<Trigger Property="IsMouseOver"
Value="true">
<Setter Property="Stroke"
Value="#FF3C7FB1"
TargetName="Circle"/>
<Setter Property="Stroke"
Value="#222"
TargetName="Sign"/>
</Trigger>
<Trigger Property="IsPressed"
Value="true">
<Setter Property="Stroke"
Value="#FF526C7B"
TargetName="Circle"/>
<Setter Property="StrokeThickness"
Value="1.5"
TargetName="Circle"/>
<Setter Property="Stroke"
Value="#FF003366"
TargetName="Sign"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- Simple Expander Template-->
<ControlTemplate x:Key="SimpleExpanderTemp" TargetType="{x:Type Expander}">
<DockPanel>
<ToggleButton x:Name="ExpanderButton"
DockPanel.Dock="Top"
Template="{StaticResource SimpleExpanderButtonTemp}"
Content="{TemplateBinding Header}"
IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
OverridesDefaultStyle="True"
Padding="1.5,0">
</ToggleButton>
<ContentPresenter x:Name="ExpanderContent"
Grid.Row="1"
Visibility="Collapsed"
DockPanel.Dock="Bottom"/>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter TargetName="ExpanderContent" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Also i am adding the following code for datagridtemplatecolumn.
<DataGridTemplateColumn Width="27">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Expander Template="{StaticResource SimpleExpanderTemp}" Expanded="Expander_Expanded" Collapsed="Expander_Collapsed"/>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
But if i am trying to expand one expander button in my wpf datagrid, some of the other expander buttons are also expanding(not every time) and some of the expander buttons are collapsing.
What is the error in this xaml code?
The expander events are,
private void Expander_Expanded(object sender, RoutedEventArgs e)
{
ContentControl cc = sender as ContentControl;
Expander exp = cc as Expander;
var itemsSource = objDatagrid.ItemsSource as IEnumerable;
if (itemsSource != null)
{
foreach (var item in itemsSource)
{
var row = objDatagrid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;
if (row != null)
{
row.IsSelected = false;
}
}
}
for (var vis = sender as Visual; vis != null; vis = VisualTreeHelper.GetParent(vis) as Visual)
if (vis is DataGridRow)
{
var row = (DataGridRow)vis;
row.IsSelected = true;
if (exp.IsExpanded)
{
row.DetailsVisibility = Visibility.Visible;
exp.ExpandDirection = ExpandDirection.Down;
}
break;
}
}
private void Expander_Collapsed(object sender, RoutedEventArgs e)
{
var itemsSource = objDatagrid.ItemsSource as IEnumerable;
if (itemsSource != null)
{
foreach (var item in itemsSource)
{
var row = objDatagrid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;
if (row != null)
{
row.IsSelected = false;
}
}
}
for (var vis = sender as Visual; vis != null; vis = VisualTreeHelper.GetParent(vis) as Visual)
if (vis is DataGridRow)
{
var row = (DataGridRow)vis;
row.IsSelected = true;
row.DetailsVisibility = row.DetailsVisibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
break;
}
}
You could try RowDetailsTemplate for the dataGrid. Also set the RowDetailsVisibilityMode="VisibleWhenSelected"
<DataGrid SelectionMode="Extended" ItemsSource="{Binding}" RowDetailsVisibilityMode="VisibleWhenSelected">
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="5">
<!-- Content -->
</StackPanel>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
<DataGrid.Columns>
<!-- Columns -->
</DataGrid.Columns>
</DataGrid>
</Grid>

Change dot for comma in chart labels Charting c#

i have to change the decimal separator of the labels of my chart. I can't put them directly like string because they need a doublé to make the chart.
Here is the code:
private static byte[] ObtenerBarraDoble(IList<ValorBarraDTO> valores)
{
var newColor1 = Color.FromArgb(187, 189, 191);
var newColor2 = Color.FromArgb(0, 138, 209);
using (var graficoPie = new Chart { Height = 200, Width = 700, RenderType = RenderType.BinaryStreaming })
{
var chartAreaPie = new ChartArea();
//chartAreaPie.AxisX.LabelStyle.Format = "dd/MMM\nhh:mm";
chartAreaPie.AxisX.MajorGrid.LineColor = Color.White;
chartAreaPie.AxisY.MajorGrid.LineColor = Color.White;
chartAreaPie.AxisX.LabelStyle.Font = new System.Drawing.Font("Trebuchet MS", 8f);
chartAreaPie.AxisY.LabelStyle.Font = new System.Drawing.Font("Trebuchet MS", 8f);
chartAreaPie.AxisX.LabelStyle.Format = "N0";
chartAreaPie.AxisY.LabelStyle.Format = "N0";
graficoPie.ChartAreas.Add(chartAreaPie);
var serieNuevo = new Series("Cartera Actual")
{
ChartType = SeriesChartType.Column,
XValueMember = "label",
YValueMembers = "valor1",
Color = newColor1,
Legend = "Cartera Actual",
IsValueShownAsLabel = true,
LabelFormat = "N1",
CustomProperties = "LabelStyle=Top"
};
graficoPie.Series.Add(serieNuevo);
var serie = new Series("Cartera Recomendada")
{
ChartType = SeriesChartType.Column,
XValueMember = "label",
YValueMembers = "valor2",
Color = newColor2,
Legend = "Cartera Propuesta",
IsValueShownAsLabel = true,
LabelFormat = "N1",
CustomProperties = "LabelStyle=Top"
};
graficoPie.Series.Add(serie);
graficoPie.DataSource = valores;
return PdfHelper.ChartABinario(graficoPie);
}
}
I think maybe in CustomProperties? i need to do this, please help!
Can you tell me if you are using XAML? The key is the template style formatting. This is how i did some formatting. If it doesn't help, I apologize for wasting your time.
<Style x:Key="SeriesColumn" TargetType="DVC:ColumnDataPoint">
<Setter Property="Background" Value="{Binding BackColor}"></Setter>
<Setter Property="Foreground" Value="{Binding ForeColor}"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DVC:ColumnDataPoint">
<Grid>
<Rectangle
Fill="{TemplateBinding Background}"
Stroke="Black"
StrokeThickness="1"
/>
<Grid
Background="Transparent"
Margin="{Binding SeriesMargin}"
HorizontalAlignment="Stretch"
VerticalAlignment="Top">
<TextBlock
HorizontalAlignment="Center"
Background="Transparent"
Foreground="{TemplateBinding Foreground}"
Text="{TemplateBinding FormattedDependentValue}"
FontWeight="Bold"
FontSize="12"
/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The key is the Template and the TetBlock. if think it's possible to go deep enough to be able to replace , with a .

Categories