I have a combobox in a styled window.
I am perfectly aware that the problem resides in the style but since is a company style and so I can't change it GLOBALLY. What I want to do is OVVERRIDE it whenever I am in need.
So as you see in the picture above the main problem is the background which is dark. And then, minor problem, it shows no caret.
The xaml is:
<ComboBox Name="cmbOptions" Grid.Row="6" Background="White" Width="300" Margin="10" BorderBrush="Black" Height="20" Foreground="Black" IsEditable="False">
Thank you for your help
Patrick
--ADD--
I have tried that
<ComboBox.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.WindowBrushKey}" Color="Yellow" />
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red" />
</ComboBox.Resources>
but no luck!
--ADD2--
I even changed it in code behind
//cmbOptions.ItemsSource = obcCategories;
for (int i = 0; i < ...; i++)
{
ComboBoxItem item = new ComboBoxItem();
item.Background = Brushes.White;
item.Content = "AAA";
ibw.cmbOptions.Items.Add(item);
}
but it didn't work for background but it did for foreground.
---ADD3---
---ADD4---
You should just override global style in Window or UserControl where you use your ComboBox. See an example:
<Window x:Class="DataGridSelectedItemsWpfApplication.MainWindow"
...The code omitted for the brevity...
Title="MainWindow" WindowStartupLocation="CenterScreen" Height="350" Width="525">
<Window.Resources>
<Style TargetType="{x:Type ComboBoxItem}" BasedOn="{StaticResource {x:Type ComboBoxItem}}">
<Setter Property="Background" Value="Green" />
</Style>
</Window.Resources>
<Grid>
<ComboBox Name="comboBox">
<ComboBoxItem Content="The first item"/>
<ComboBoxItem Content="The second item"/>
<ComboBoxItem Content="The third item"/>
</ComboBox>
</Grid>
</Window>
Update:
If you want to change background programatically, please see the following code:
private void SomeMethod()
{
ComboBoxItem item = new ComboBoxItem();
for (int start = 0; start < 10; start++)
{
if (item == null)
item = new ComboBoxItem();
item.Background= Brushes.Green;
item.Content = start.ToString();
comboBox.Items.Add(item);
item = null;
}
}
Your code works excellently. You should just remove cmbOptions from ibw.cmbOptions.Items.Add(item); like that:
for (int i = 0; i < 10; i++)
{
ComboBoxItem item = new ComboBoxItem();
item.Background = Brushes.Yellow;
item.Content = "AAA";
comboBox.Items.Add(item);
}
What I have if I use your code:
Update 1:
It is really interesting why it is not working. Just another try:)
<Window x:Class="WpfApplication2.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>
<StackPanel Orientation="Horizontal" >
<ComboBox Name="comboBox">
<ComboBox.Resources>
<Style TargetType="{x:Type ComboBoxItem}" BasedOn="{StaticResource {x:Type ComboBoxItem}}">
<Setter Property="Background" Value="Green" />
</Style>
</ComboBox.Resources>
<ComboBoxItem Content="1"/>
<ComboBoxItem Content="2"/>
<ComboBoxItem Content="3"/>
</ComboBox>
</StackPanel>
</Grid>
</Window>
Update2:
I've made a sample for view. Hope it helps.
https://onedrive.live.com/redir?resid=D6BDF30773C16E01!2062&authkey=!AFw5eVP7NrZlus0&ithint=file%2crar
Related
I tried different things but without success
I have to size the window relative to the dynamic numbers of tiles (MahApps.Metro) but only in height, once the height exceeded of my screen I put a scroolbar
In my window I have for the moment:
<Controls:MetroWindow x:Class="EpiTUILE.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
Title="EpiTUILE" Height="270" Width="400" ShowMaxRestoreButton="False" ShowCloseButton="False"
Top="0" Loaded="MetroWindow_Loaded" Icon="Alerte.png" Closing="MetroWindow_Closing"
MouseMove="MetroWindow_MouseMove" ResizeMode="CanMinimize" MouseEnter="MetroWindow_MouseEnter"
StateChanged="MetroWindow_StateChanged" WindowStyle="None" UseLayoutRounding="True"
AllowsTransparency="True" Background="Transparent" WindowState="Minimized">
<Window.Resources>
<Style x:Key="TileStyle" TargetType="Controls:Tile">
<EventSetter Event="PreviewMouseDown" Handler="OnTileClick" />
<Setter Property="Width" Value="380" />
<Setter Property="Height" Value="70" />
<Setter Property="TitleFontSize" Value="10" />
</Style>
</Window.Resources>
<Grid Height="Auto">
<ScrollViewer x:Name="MyScrollViewer" VerticalScrollBarVisibility="Auto" Grid.Row="1" Width="Auto" Height="Auto" Grid.ColumnSpan="2" ScrollViewer.FlowDirection="LeftToRight" >
<WrapPanel Name="PanelTile" Orientation="Vertical" HorizontalAlignment="Center" Height="Auto" >
</WrapPanel>
</ScrollViewer>
</Grid>
I then build my tiles in code behind:
PanelTile.Children.Clear();
for (int i = 0; i < _nbrTile; i++)
{
Tile _tile = new Tile();
_tile.HorizontalTitleAlignment = HorizontalAlignment.Right;
_tile.Title = i.ToString();
_tile.Style = this.FindResource("TileStyle") as Style;
_tile.Content = "Type Alerte " + i;
PanelTile.Children.Add(_tile);
}
I am using Chart tool. Here is my wpf code:
<Window x:Class="UserGraphShow.GraphOutput"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:DVC="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"
mc:Ignorable="d"
Title="MainWindow" Height="446" Width="726" >
<Grid>
<DVC:Chart Name="Chart" Grid.ColumnSpan="3" Background="Blue" Title="Line">
<DVC:Chart.Series>
<DVC:LineSeries Title=" Your Graph" IndependentValueBinding="{Binding Path=Key}" DependentValueBinding="{Binding Path=Value}" Opacity="0" />
</DVC:Chart.Series>
<DVC:Chart.DataContext >
<Style TargetType="Grid" >
<Setter Property="Opacity" Value="0" />
</Style>
</DVC:Chart.DataContext>
<DVC:Chart.Axes>
<DVC:LinearAxis Orientation="Y" Minimum="-302" Maximum="0"/>
<DVC:LinearAxis Orientation="X" Maximum="509" Minimum="0"/>
<DVC:LinearAxis Visibility="Hidden"/>
</DVC:Chart.Axes>
</DVC:Chart>
<Button x:Name="Button" Content="Show" HorizontalAlignment="Left" Margin="8,10,0,0" VerticalAlignment="Top" Width="75" Grid.Column="1" Height="22" Click="button_Click"/>
</Grid>
</Window>
I am trying to display arrays of x[] and y[] as a plot.
Here is code of a button:
private void button_Click(object sender, RoutedEventArgs e)
{
var b = GetUserGraphUnfoInfo.FindXy("../../../Main_Logic/image.jpeg");
var x = b[0]; // array of x
var y = b[1]; // array of y
var ls = new LineSeries
{
IndependentValueBinding = new Binding("Key"),
DependentValueBinding = new Binding("Value")
};
var a = new KeyValuePair<int, int>[x.Length-1];
for (var i = 0; i < x.Length-1; i++)
a[i] = new KeyValuePair<int, int>(x[i], y[i]);
ls.ItemsSource = a;
Chart.Series.Clear();
Chart.Series.Add(ls);
}
Everything works ok, though the dots are too big, how do i remove them at all?
Here is what i get:
Create and apply a style to your data points, as below:
XAML:
<Window x:Class="WpfApplication342.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:dvc="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"
xmlns:local="clr-namespace:WpfApplication342"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<PointCollection>1,10 2,20, 3,30</PointCollection>
</Window.DataContext>
<Window.Resources>
<Style x:Key="LineDataPointStyle1" TargetType="{x:Type dvc:LineDataPoint}">
<Setter Property="Background" Value="Orange"/>
<Setter Property="BorderBrush" Value="Gray"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Width" Value="64"/>
<Setter Property="Height" Value="64"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type dvc:LineDataPoint}">
<Grid x:Name="Root" Opacity="1">
<Grid.ToolTip>
<ContentControl Content="{TemplateBinding FormattedDependentValue}"/>
</Grid.ToolTip>
<Ellipse Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}"/>
<Ellipse RenderTransformOrigin="0.661,0.321">
<Ellipse.Fill>
<RadialGradientBrush GradientOrigin="0.681,0.308">
<GradientStop Color="Transparent"/>
<GradientStop Color="#FF3D3A3A" Offset="1"/>
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse x:Name="SelectionHighlight" Fill="Red" Opacity="0"/>
<Ellipse x:Name="MouseOverHighlight" Fill="White" Opacity="0"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<dvc:Chart>
<dvc:LineSeries ItemsSource="{Binding}"
DependentValuePath="Y"
IndependentValuePath="X"
DataPointStyle="{DynamicResource LineDataPointStyle1}"/>
</dvc:Chart>
</Grid>
Now you can manipulate the style in several ways to eliminate the dots: use transparent colors, set width and height to zero, or even modify the control template altogether. Setting width and height to zero:
I've a TabControl like this:
<TabControl>
<TabItem Header="playing" HorizontalAlignment="Left" Width="150" Tag="Tab1">
<TabItem.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}" ToolTip="playing" />
<Image Margin="10,0,0,0" Source="/logo.png" Height="25"/>
</StackPanel>
</DataTemplate>
</TabItem.HeaderTemplate>
</TabItem>
...
In this TabControl I've three different TabItem, each tab item have a default image. My goal is to change the image TabItem where the user has positioned the mouse.
So in this case the TabItem 1 with ToolTip "playing" instead of logo.png should have logo2 when the mouse is over this tab item.
How can I do this?
Note: Please, note that I'm using mahapp, and I'm using a DataTemplate for keep the tooltip text without override the original style of mahapp tab item.
Try this:
XAML:
<Controls:MetroWindow
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:local="clr-namespace:MahApps.Metro.Application21"
x:Class="MahApps.Metro.Application21.MainWindow"
BorderThickness="1"
BorderBrush="{DynamicResource AccentColorBrush}"
Icon="mahapps.metro.logo2.png"
Title="MainWindow"
Height="350"
Width="525">
<Controls:MetroWindow.Resources>
<DataTemplate x:Key="DataTemplate1">
<StackPanel x:Name="Panel1" Orientation="Horizontal">
<TextBlock Text="{Binding Text}" ToolTip="{Binding Text}" />
<Image x:Name="Image1" Source="{Binding Logo}" Margin="10,0,0,0" Height="25"/>
</StackPanel>
<DataTemplate.Triggers>
<Trigger SourceName="Panel1" Property="IsMouseOver" Value="true" >
<Setter TargetName="Image1" Property="Source" Value="logo4.png" />
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</Controls:MetroWindow.Resources>
<Controls:MetroWindow.DataContext>
<local:MyViewModel/>
</Controls:MetroWindow.DataContext>
<Grid>
<TabControl ItemsSource="{Binding Data}" ItemTemplate="{StaticResource DataTemplate1}">
</TabControl>
</Grid>
ViewModel:
public class MyViewModel
{
public ObservableCollection<MyData> Data { get; set; }
public MyViewModel()
{
Data = new ObservableCollection<MyData>
{
new MyData {Logo = "logo1.png", Text = "playing 1" },
new MyData {Logo = "logo2.png", Text = "playing 2" },
new MyData {Logo = "logo3.png", Text = "playing 3" }
};
}
}
I declare a style in xaml that I need to use and apply to a user control in code behind and when I use the same style twice the following error throws:
Element already has a logical parent. It must be detached from the old
parent before it is attached to a new one.
What am I doing wrong? I need to create multiple controls of the same user-control-type in code behind and apply one and the same Style to it.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
xmlns:s="http://schemas.abtsoftware.co.uk/scichart"
x:Class="MyChartControl.MainWindow"
Title="MainWindow" Height="655" Width="1020">
<Window.Resources>
<Style x:Key="SciChartSurfaceStyle" TargetType="{x:Type s:SciChartSurface}">
<Setter Property="XAxis">
<Setter.Value>
<s:DateTimeAxis Visibility="Visible"
TextFormatting="dd/MM/yyyy"
SubDayTextFormatting="dd/MM/yyyy HH:mm:ss.fff"
GrowBy="0.02, 0.02"/>
</Setter.Value>
</Setter>
<Setter Property="YAxis">
<Setter.Value>
<s:NumericAxis AxisAlignment="Right"
Visibility="Visible"
TextFormatting="{Binding YAxisFormatting}"
GrowBy="0.02, 0.02"
AutoRange="Always"/>
</Setter.Value>
</Setter>
<Setter Property="ChartModifier">
<Setter.Value>
<s:ModifierGroup>
<s:RubberBandXyZoomModifier IsAnimated = "False" IsXAxisOnly = "True" ExecuteOn = "MouseRightButton"/>
<s:ZoomPanModifier XyDirection="XYDirection" ClipModeX = "ClipAtExtents" ExecuteOn ="MouseLeftButton" />
<s:MouseWheelZoomModifier XyDirection = "XYDirection"/>
<s:ZoomExtentsModifier IsAnimated = "False" ExecuteOn = "MouseDoubleClick" />
<s:XAxisDragModifier DragMode = "Scale"/>
<s:CursorModifier SourceMode="AllSeries" UseInterpolation="True"/>
<s:LegendModifier ShowLegend="True" LegendPlacement ="Inside" GetLegendDataFor="AllSeries" Margin="10"/>
<!--<s:SeriesSelectionModifier ReceiveHandledEvents="True">
<s:SeriesSelectionModifier.SelectedSeriesStyle>
<Style TargetType="s:BaseRenderableSeries">
<Setter Property="SeriesColor" Value="White"/>
<Setter Property="PointMarkerTemplate">
<Setter.Value>
<ControlTemplate>
<s:EllipsePointMarker Fill="#FF00DC" Stroke="White" Width="7" Height="7"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</s:SeriesSelectionModifier.SelectedSeriesStyle>
</s:SeriesSelectionModifier>-->
</s:ModifierGroup>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="32" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" Background="Black">
<TextBlock Text="Dataseries Type:" Margin="5,0" VerticalAlignment="Center" FontSize="12" Foreground="White"/>
<ComboBox x:Name="ComboBox_ChooseSeriesType" MinWidth="140" Margin="5,3" VerticalContentAlignment="Center"/>
<TextBlock Text="Theme:" Margin="5,0" VerticalAlignment="Center" FontSize="12" Foreground="White"/>
<ComboBox x:Name="ComboBox_ChooseTheme" MinWidth="140" Margin="5,3" VerticalContentAlignment="Center"/>
</StackPanel>
<dxdo:LayoutGroup Grid.Row="1" x:Name="LayoutGroup" Orientation="Vertical">
<!--<dxdo:LayoutPanel Name="Panel1">
<s:SciChartSurface Name="Surface1" Style="{StaticResource SciChartSurfaceStyle}"></s:SciChartSurface>
</dxdo:LayoutPanel>-->
</dxdo:LayoutGroup>
</Grid>
And the code-behind method that retrieves the style and applies it:
private void TestSomeStuff()
{
var style = this.TryFindResource("SciChartSurfaceStyle") as Style;
var sciChartSurface1 = new SciChartSurface() {Style = style};
var panel1 = new LayoutPanel(){Content=sciChartSurface1};
var style2 = this.TryFindResource("SciChartSurfaceStyle") as Style;
var sciChartSurface2 = new SciChartSurface() {Style = style2};
var panel2 = new LayoutPanel() {Content = sciChartSurface2};
LayoutGroup.Add(panel1);
LayoutGroup.Add(panel2);
}
EDIT
Adding panel1 to LayoutGroup works just fine but the run-time error occurs as soon as I attempt to add panel2. Also, as long as do not inject style into a new instance of SciChartSurface it works just fine. The error pops up as soon as I inject the style into both new surfaces.
Do not set Style in code behind directly:
var style = this.TryFindResource("SciChartSurfaceStyle") as Style;
var sciChartSurface1 = new SciChartSurface() {Style = style};
but with SetValue method:
var style = this.TryFindResource("SciChartSurfaceStyle") as Style;
var sciChartSurface1 = new SciChartSurface();
sciChartSurface1.SetValue(StyleProperty, style);
I have a DataGrid filled with instances of a class that exposes a double type property. This property is shown into the DataGrid. I want to implement a custom validation, and I want to color the whole cell red if this validation fails. I think I am close to making it work, but not quite yet, and now I'm stumped.
My problem is that I cannot make the conditional (on validation fail) formatting work. The result is that the cells are correctly colored at the start, but when I insert a value that makes the falidating function return false, I get the usual red border, white background cell style.
How am I supposed to input this formatting style?
XAML code:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<DataGrid x:Name="dg" ItemsSource="{Binding Data}">
<DataGrid.Resources>
<ControlTemplate x:Key="validationTemplate">
<DockPanel>
<AdornedElementPlaceholder/>
<TextBlock Foreground="Red" FontSize="20">!</TextBlock>
</DockPanel>
</ControlTemplate>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="Yellow"/>
<Setter Property="Validation.ErrorTemplate" Value="{StaticResource validationTemplate}"></Setter>
</Style>
</DataGrid.Resources>
</DataGrid>
</Window>
Code behind:
public partial class MainWindow : Window
{
...
private void DataGrid_AutoGeneratedColumns(object sender, EventArgs e)
{
foreach (DataGridTextColumn c in dg.Columns)
{
c.ElementStyle = (Style)dg.FindResource("s");
for (int i = 0; i < dg.Items.Count; i++)
{
DataGridRow row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(i);
if (row == null) // May be virtualized, bring into view and try again.
{
dg.UpdateLayout();
dg.ScrollIntoView(dg.Items[i]);
row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(i);
}
TextBlock tb = (TextBlock)c.GetCellContent(row);
Binding binding = BindingOperations.GetBinding(tb, TextBlock.TextProperty);
binding.ValidationRules.Clear();
binding.ValidationRules.Add(new VR());
}
}
}
}
public class VR : ValidationRule
{
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
...
}
}
EDIT: updated XAML code according to dev hedgehog's suggestion, still not working.
You seem to be using ErrorTemplate wrong.
Take a look at this:
<ControlTemplate x:Key="validationTemplate">
<DockPanel>
<TextBlock Foreground="Red" FontSize="20">!</TextBlock>
<AdornedElementPlaceholder/>
</DockPanel>
</ControlTemplate>
<TextBox Name="textBox1" Width="50" FontSize="15"
Validation.ErrorTemplate="{StaticResource validationTemplate}"
Style="{StaticResource textBoxInError}"
Grid.Row="1" Grid.Column="1" Margin="2">
<TextBox.Text>
<Binding Path="Age" Source="{StaticResource ods}"
UpdateSourceTrigger="PropertyChanged" >
<Binding.ValidationRules>
<c:AgeRangeRule Min="21" Max="130"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
Validation.ErrorTemplate will allow you to decorate AdornedElementPlaceholder which is in this case TextBox.
In the example I gave you a red ! will be decorated to the left of the TextBox.
Edit:
I changed your code to make it work.
<Grid>
<DataGrid x:Name="dg" ItemsSource="{Binding Data}" PreparingCellForEdit="OnBeginningEdit">
<DataGrid.Resources>
<ControlTemplate x:Key="validationTemplate">
<DockPanel>
<AdornedElementPlaceholder/>
<TextBlock Foreground="Red" FontSize="20">!</TextBlock>
</DockPanel>
</ControlTemplate>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="Yellow"/>
<Setter Property="Validation.ErrorTemplate" Value="{StaticResource validationTemplate}"/>
</Style>
</DataGrid.Resources>
</DataGrid>
</Grid>
This is the code behind
public partial class MainWindow : Window
{
public List<D> Data { get; set; }
public MainWindow()
{
Data = new List<D>();
Random r = new Random();
Data.Add(new D(r.NextDouble()));
Data.Add(new D(r.NextDouble()));
Data.Add(new D(r.NextDouble()));
InitializeComponent();
DataContext = this;
}
private void DataGrid_AutoGeneratedColumns(object sender, EventArgs e)
{
foreach (DataGridTextColumn c in dg.Columns)
{
c.EditingElementStyle = (Style)dg.FindResource("s");
}
}
private void OnBeginningEdit(object sender, DataGridPreparingCellForEditEventArgs e)
{
TextBox tbx = (TextBox)e.EditingElement;
Binding binding = BindingOperations.GetBinding(tbx, TextBox.TextProperty);
binding.ValidationRules.Clear();
binding.ValidationRules.Add(new VR());
}
}
See you need to work with TextBoxes and when you write something inside one then click away in order to trigger validation.
Try it out. It works for me :)