<Window.Resources >
<Style x:Name="stylepropery" x:Key="BaseContentControlStyle" TargetType="{x:Type ContentControl}">
<Setter Property="Foreground" Value="{DynamicResource MyFillBrush}" />
</Style>
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource BaseContentControlStyle}" />
<Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource BaseContentControlStyle}" />
</Window.Resources>
which is applying common font color to all the labels and textboxes now i want to change the color of font from code behind but some how its not applying
i just want to change setter propery value
Setter setter = new Setter(ContentControl.ForegroundProperty, dt.Rows[0]["value"]);
Style style = this.FindResource("BaseContentControlStyle") as Style;
style.Setters.Add(setter);
I have used this but not succedd
Try this code this may help you
Style style = new Style(typeof(ContentControl));
style.Setters.Add(new Setter(ContentControl.ForegroundProperty, Brushes.Green));
Resources["BaseContentControlStyle"] = style;
var converter = new System.Windows.Media.BrushConverter();
var brush = (Brush)converter.ConvertFromString(dt.Rows[0]["value"].ToString());
Style st = this.Resources["BaseContentControlStyle"] as Style;
Random r = new Random();
this.Resources["MyFillBrush"] = (new BrushConverter().ConvertFrom(dt.Rows[0]["value"].ToString()));
After lots of googling i have found the solution i am adding this solution for the future refrence users so they don't have to search many things :)
Related
I have a DataGrid with its RowStyle set in XAML:
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}" BasedOn="{StaticResource {x:Type DataGridRow}}">
<Setter Property="VerticalAlignment" Value="Center"/>
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="LightSteelBlue"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Aquamarine"/>
<Setter Property="Foreground" Value="Black"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
The DataGrid contains rowdetails which I wish to print when that row is selected. However, I need to change the background colour of the row (including its rowdetails) from Aquamarine to White when printing and then back again after printing. I have the following method to achieve this:
private void ChangeStyle(bool printing)
{
Style rsRowStyle = new Style();
Style oldStyle = dgdCustomersListing.RowStyle;
Trigger DataTrigger = new Trigger();
DataTrigger.Property = DataGridRow.IsSelectedProperty;
DataTrigger.Value = true;
rsRowStyle.Triggers.Add(DataTrigger);
Setter TriggerSetter = new Setter();
TriggerSetter.Property = DataGridRow.BackgroundProperty;
TriggerSetter.Value = Brushes.LightGray;
rsRowStyle.Setters.Add(TriggerSetter);
dgdCustomersListing.RowStyle = printing ? rsRowStyle : oldStyle;
}
This works fine when first called for printing (the row background converts to white), but calling the method again when printing is false fails to revert the DataGrid back to the original style.
Why does it not work?
My error: the assignment to oldStyle needs to be made when first calling the printing method, and then passing that value to the ChangeStyle method so that it is not changed by that method. Hence:
private void ChangeStyle(bool printing, Style oldStyle)
{
Style rsRowStyle = new Style();
Trigger DataTrigger = new Trigger();
DataTrigger.Property = DataGridRow.IsSelectedProperty;
DataTrigger.Value = true;
rsRowStyle.Triggers.Add(DataTrigger);
Setter TriggerSetter = new Setter();
TriggerSetter.Property = DataGridRow.BackgroundProperty;
TriggerSetter.Value = Brushes.LightGray;
rsRowStyle.Setters.Add(TriggerSetter);
dgdCustomersListing.RowStyle = printing ? rsRowStyle : oldStyle;
}
I have left this up as Q&A as it took me some time to sort out how to change the style in code, and I hope this might be useful to others.
I did not find it on the Internet
Help rewrite this code to C#
<Style x:Key="GroupHeaderStyle" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander x:Name="exp" IsExpanded="True" >
<Expander.Header>
<TextBlock/>
</Expander.Header>
<ItemsPresenter/>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
My code
An error in the code takes off.
Style GroupStyle = new Style() { TargetType = typeof(GroupItem) };
Setter setter = new Setter { Property = Control.TemplateProperty };
ControlTemplate template = new ControlTemplate { TargetType = typeof(GroupItem) };
var expander = new FrameworkElementFactory(typeof(Expander));
expander.SetValue(Expander.IsExpandedProperty, false);
expander.SetValue(Expander.HeaderProperty, new TextBlock { }); // Error: System.NotSupportedException
expander.SetValue(Expander.ContentProperty, new ItemsPresenter());
template.VisualTree = expander;
setter.Value = template;
GroupStyle.Setters.Add(setter);
Doing datagrid grouping
As #arconaut has said, first line should use typeof. So first tree lines are:
Style GroupStyle = new Style() { TargetType = typeof(GroupItem) };
Setter setter = new Setter { Property = Control.TemplateProperty };
ControlTemplate template = new ControlTemplate { TargetType = typeof(GroupItem) };
Then I believe IsExpandedProperty should be set to True based on the above XAML.
expander.SetValue(Expander.IsExpandedProperty, true);
Finally you need to pass FrameworkElementFactory as argument for SetValue() in the last two lines.
expander.SetValue(Expander.HeaderProperty,
new FrameworkElementFactory(typeof(TextBlock)));
expander.SetValue(Expander.ContentProperty,
new FrameworkElementFactory(typeof(ItemsPresenter)));
Try replacing your first line with this:
Style GroupStyle = new Style() { TargetType = typeof(GroupItem) };
The x:Type markup extension has a similar function to the typeof() operator in C#
https://learn.microsoft.com/en-us/dotnet/desktop/xaml-services/xtype-markup-extension
I'm trying to do this XAML:
<UserControl.Resources>
<Style TargetType="Label">
<Setter Property="Foreground" Value="Blue"/>
</Style>
</UserControl.Resources>
in C# code.
Here's my attempt in the UserControl Constructor:
InitializeComponent();
string labelForegroundColor = "Blue";
string labelXAMLStyle = #"<Style xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' TargetType=""Label"">
<Setter Property=""Foreground"" Value=""{LabelForegroundColor}""/>
</Style>";
labelXAMLStyle = labelXAMLStyle.Replace("{LabelForegroundColor}", labelForegroundColor);
StringReader mainLabelStyleXAMLStringReader = new StringReader(labelXAMLStyle);
XmlReader mainLabelStyleXAMLXMLReader = XmlReader.Create(mainLabelStyleXAMLStringReader);
Style mainLabelStyle = (Style)XamlReader.Load(mainLabelStyleXAMLXMLReader);
this.Resources.Add("LabelStyle", mainLabelStyle);
When I have the XAML in my UserControl it obviously works, but when I remove the XAML and add the code in my UserControl Constructor; it doesn't.
Where am I going wrong?
Do I have to add some sort of Resource Dictionary?
How can I get it right to set the style of all Label's in my one specific UserControl?
You can try to create a style programatically and then add it to the resources.
Style style = new Style(typeof(Label));
style.Setters.Add(new Setter(Label.ForegroundProperty, Brushes.Blue));
Resources[typeof(Label)] = gridStyle;
I am making a minesweeper clone for class. The basic game board is generated through code, but it is a series of ListView columns containing rows of Tile objects. This code generates the ListViews (it works fine):
// Create as many lists as necessary to fill the board according to the size specified
void createGameBoard(bool erase = true)
{
// Erase any previous game
if(erase)
{
for(int i = mainGameBoard.Children.Count; i > 0; i--)
{
mainGameBoard.Children.RemoveAt(i - 1);
}
}
// Main Game Board
// column 0 column 1 column 2
// tile 0,0 tile 1,0 tile 2,0
// tile 0,1 tile 1,1 tile 2,1
// tile 0,2 tile 1,2 tile 2,2
// Create a new list view for each game board column
for(uint col = 0; col < minesweepGame.Width; col++)
{
ListView column = new ListView();
column.Name = col.ToString();
column.SelectionMode = ListViewSelectionMode.None;
column.IsItemClickEnabled = true;
column.ItemClick += Column_ItemClick;
///column.ItemContainerStyleSelector.SelectStyle()
// Fill the column with tiles
Tile[] columnTiles = new Tile[minesweepGame.Width];
for(uint row = 0; row < minesweepGame.Width; row++)
{
columnTiles[row] = minesweepGame.TileList[col, row];
}
column.ItemsSource = columnTiles;
// Append the newly created column to the main game board (in order of creation)
mainGameBoard.Children.Add(column);
}
}
This results in a clean grid with animations.
UWP Minesweeper using ListViews
I want to style items differently when they are revealed to the user (once it is clicked, a tile becomes darker and has numbers with different colours). So I looked at the documentation and examples, and created a StyleSelector:
public class ColumnTileSelector : StyleSelector
{
private Style Tile0 = new Style(typeof(ListViewItem));
private Style Tile1 = new Style(typeof(ListViewItem));
private Style Tile2 = new Style(typeof(ListViewItem));
private Style Tile3 = new Style(typeof(ListViewItem));
private Style Tile4 = new Style(typeof(ListViewItem));
protected override Style SelectStyleCore(object item, DependencyObject container)
{
Tile tile = (Tile)item;
if(tile.IsShownGraphically)
{
switch(tile.AdjacentMines)
{
case 0:
Tile0.Setters.Add(new Setter(Control.BackgroundProperty, Colors.Red));
return Tile0;
case 1:
return Tile1;
case 2:
return Tile2;
case 3:
return Tile3;
case 4:
return Tile4;
default:
return Tile0;
}
}
else
{
return Tile0;
}
}
}
I also had previously created styles in the XAML:
<!-- style the game grid tiles -->
<Page.Resources>
<Style TargetType="ListViewItem">
<Setter Property="MinWidth" Value="30"/>
<Setter Property="MinHeight" Value="30"/>
<Setter Property="MaxWidth" Value="30"/>
<Setter Property="MaxHeight" Value="30"/>
<Setter Property="Padding" Value="2, 2, 2, 2"/>
<Setter Property="BorderBrush" Value="SlateGray"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="FontWeight" Value="ExtraBlack"/>
<Setter Property="Foreground" Value="DarkBlue"/>
</Style>
<Style TargetType="ListViewItem" x:Key="Tile0">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="Transparent"/>
</Style>
<Style TargetType="ListViewItem" x:Key="Tile1">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="DarkBlue"/>
</Style>
<Style TargetType="ListViewItem" x:Key="Tile2">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="Green"/>
</Style>
<Style TargetType="ListViewItem" x:Key="Tile3">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="Red"/>
</Style>
<Style TargetType="ListViewItem" x:Key="Tile4">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="DarkOrange"/>
</Style>
<Style TargetType="StackPanel" x:Key="mainGameBoard">
<Setter Property="BorderBrush" Value="SlateGray"/>
<Setter Property="BorderThickness" Value="0"/>
</Style>
<local:ColumnTileSelector x:Key="tileColor"/>
</Page.Resources>
However, nothing actually works.
How do I refer to styles from the XAML in the view's code?
More importantly, how do I specify that my ListViews should use the ColumnTileSelector?
In the code that generates the ListViews, I commented out ///column.ItemContainerStyleSelector.SelectStyle(). Is it possible to specify my ColumnTileSelector class here? I'm confused.
The documentation is not clear on how things are connected together. I understand in principle, but none of the examples I see specify why things react as they do.
<Page>
<Page.Resources>
<Style TargetType="ListViewItem" x:Key="Tile1">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="DarkBlue"/>
</Style>
<support:ColumnStyleSelector x:Key="ColumnStyleSelector"
Tile1="{StaticResource Tile1}"/>
</Page.Resources>
<Grid>
<ListView ItemContainerStyleSelector="{StaticResource ColumnStyleSelector}"/>
</Page>
Make the styles Tile1, Tile2, etc public properties of the ColumnStyleSelector
Put the Styles in the page Resources
Put the ColumnStyleSelector in the page Resources
Reference the Styles in the Resources in the ColumnStyleSelector attributes
Referring to style in the view code required a couple steps. First, create a page-type variable in the view: static MainPage mainPage; Second, initialize it in the page constructor: mainPage = this; Third, use the style in the view controller: mainPage.Resources["TileExploded"] as Style;
To specify which StyleSelector a list view must use programmatically, use this code: column.ItemContainerStyleSelector = new ColumnStyleSelector();, where column is a ListView.
As a result, it is possible to renderListViewItem elements with different styles using logic in the StyleSelector:
// Selects what style applies to a list view item according to that item's properties when it is rendered
public class ColumnStyleSelector : StyleSelector
{
protected override Style SelectStyleCore(object item, DependencyObject container)
{
Tile tile = (Tile)item;
if(tile.Type == (int)TileType.ExplodedMine)
{
return mainPage.Resources["TileExploded"] as Style;
}
else if(tile.IsRevealed == true && tile.IsShownGraphically == true)
{
switch(tile.AdjacentMines)
{
case 0:
return mainPage.Resources["Tile0"] as Style;
case 1:
return mainPage.Resources["Tile1"] as Style;
case 2:
return mainPage.Resources["Tile2"] as Style;
case 3:
return mainPage.Resources["Tile3"] as Style;
case 4:
return mainPage.Resources["Tile4"] as Style;
default:
return mainPage.Resources["ListViewItem"] as Style;
}
}
else
{
return mainPage.Resources["ListViewItem"] as Style;
}
}
}
This, of course, can use any logic specific to the program, with the key statements being return mainPage.Resources["XAML Resource Style Key Here"] as Style;
I'm programming a WPF class library mainly based on C# code and I'm currently trying to load XAML file only for styling UI Elements.
Here is the XAML "style" code with "BuildAction : Content" :
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1">
<Style x:Key="LabelStyle" TargetType="{x:Type Label}">
<Setter Property="Height" Value="53" />
<Setter Property="Width" Value="130" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Margin" Value="99,71,0,0" />
<Setter Property="VerticalAlignment" Value= "Top" />
<Setter Property="Foreground" Value="#FFE75959" />
<Setter Property="FontFamily" Value="Calibri" />
<Setter Property="FontSize" Value="40" />
</Style>
Here is the code for my label :
private void CreateElement(int i)
{
UIElementOut[i] = new Label();
var uiElement = (Label)UIElementOut[i];
uiElement.HorizontalAlignment = HorizontalAlignment.Center;
uiElement.VerticalAlignment = VerticalAlignment.Center;
uiElement.FontFamily = new FontFamily(FFontInput[i]);
uiElement.FontSize = Convert.ToDouble(FontSizeIn[i]);
uiElement.Content = TextIn[i];
Brush BgBrushColor = new SolidColorBrush(RGBAToMediaColor(FBgCol[i]));
Brush FgBrushColor = new SolidColorBrush(RGBAToMediaColor(FFgCol[i]));
uiElement.Background = BgBrushColor;
uiElement.Foreground = FgBrushColor;
Uri uri = new Uri("pack://application:,,,/WpfApplication1;component/WpfApplication1/Styles/LabelStyle.xaml", UriKind.Relative);
StreamResourceInfo info = Application.GetContentStream(uri);
System.Windows.Markup.XamlReader reader = new System.Windows.Markup.XamlReader();
ResourceDictionary myResourceDictionary = Application.LoadComponent(uri) as ResourceDictionary;
Application.Current.Resources.MergedDictionaries.Add(myResourceDictionary);
Style myLabelStyle = myResourceDictionary["LabelStyle"] as Style;
uiElement.Style = myLabelStyle;
}
if UriKind is set to "Relative" I get this error message :
A relative URI cannot be created because the 'uriString' parameter represents an absolute URI.
But if Urikind is set to "Absolute" then I get this one :
Cannot use absolute URI.
So in both anyway, XAML file is not loaded and style is not applied.
EDIT :
I tried this URI :
pack://application:,,,/WpfApplication1;component/Styles/LabelStyle.xaml
And get the same error.
Correct format to reference resourcefile located in a subfolder of the local assembly's project folder
pack://application:,,,/Subfolder/ResourceFile.xaml
Correct format to reference resourcefile in separate referenced assembly is
pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml
Changing your uri to
pack://application:,,,/WpfApplication1;component/Styles/LabelStyle.xaml
should solve the issue