I have to work with a 1800-Row-XAML-Definition for a single window and I want to reduce the amount of code drastically.
There are several control-definitions, which are repeated very often and I want to write Styles for some of them. One example is a Border-Definition with integrated TextBox:
<Border Grid.Column="2" Margin="1,1,5,0" Background="#bbc2ce">
<my:RibbonTextBox HorizontalContentAlignment="Center"
IsReadOnly="True" Background="#FAFAFA"
Text="{Binding Path=someViewModel.Item,Mode=OneWay}"
MinHeight="0" FontSize="12" FontWeight="Bold" FontFamily="Arial"/>
</Border>
Apart of the Binding Path, every value is exact the same over and over again. So I wrote this Style for the RibbonTextBox:
<Style TargetType="my:RibbonTextBox" x:Key="StandardRibbonTextBox">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="IsReadOnly" Value="True" />
<Setter Property="Background" Value="#FAFAFA" />
<Setter Property="MinHeight" Value="0" />
<Setter Property="FontSize" Value="12" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="FontFamily" Value="Arial" />
</Style>
Now I want to write a style for above border, and integrate the RibbonTextBox Style. Here I am so far:
<Style TargetType="Border" x:Key="borderStyle">
<Setter Property="Background" Value="#bbc2ce" />
</Style>
Is there a possibility to integrate my TextBox-Style here? And if not, does somebody know, how to resolve this issue?
Thanks in advance!
If you only need the readonly textbox, you can use DataTemplate with ContentPresenter as coded below (replaced my:RibbonTextBox with simple TextBox for demonstration). If you need read-write, you have to provide some way of binding that allows read-write. This can be achieved with ControlTemplate (also in sample code).
<Grid x:Name="grid1">
<Grid.Resources>
<Style TargetType="TextBox" x:Key="StandardRibbonTextBox">
<!--Changed that one from HorizontalAlignment, in comparison to the question-->
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="IsReadOnly" Value="True" />
<Setter Property="Background" Value="#FAFAFA" />
<Setter Property="MinHeight" Value="0" />
<Setter Property="FontSize" Value="12" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="FontFamily" Value="Arial" />
</Style>
<Style TargetType="Border" x:Key="borderStyle">
<Setter Property="Background" Value="#bbc2ce" />
<Setter Property="Margin" Value="1,1,5,0"/>
<Setter Property="Padding" Value="5"/>
</Style>
<DataTemplate x:Key="borderedTextboxTemplate" DataType="{x:Type sys:String}">
<Border Style="{StaticResource borderStyle}">
<!--This is not going to work for two way binding (IsReadOnly="False" and Text="{Binding Mode=TwoWay}")-->
<TextBox Style="{StaticResource StandardRibbonTextBox}" Text="{Binding Mode=OneWay}"/>
</Border>
</DataTemplate>
<ControlTemplate x:Key="borderedTextboxControlTemplate" TargetType="TextBox">
<Border Style="{StaticResource borderStyle}">
<!--This is not going to work for two way binding (IsReadOnly="False" and Text="{Binding Mode=TwoWay}")-->
<TextBox Style="{StaticResource StandardRibbonTextBox}" Text="{Binding Text,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}"/>
</Border>
</ControlTemplate>
<Style x:Key="borderedTextboxControlStyle" TargetType="TextBox">
<Setter Property="Template" Value="{StaticResource borderedTextboxControlTemplate}"/>
</Style>
</Grid.Resources>
<StackPanel Margin="10">
<!--Using Controls directly-->
<Border Style="{StaticResource borderStyle}">
<TextBox
Text="{Binding Path=someViewModel.Item,Mode=OneWay}"
Style="{StaticResource StandardRibbonTextBox}"/>
</Border>
<Separator Margin="10"/>
<!--Using DataTemplate-->
<ContentPresenter
Content="{Binding Path=someViewModel.Item,Mode=OneWay}"
ContentTemplate="{StaticResource borderedTextboxTemplate}"/>
<Separator Margin="10"/>
<!--Using ControlTemplate via Style-->
<TextBox Text="{Binding Path=someViewModel.Item,Mode=OneWay}" Style="{StaticResource borderedTextboxControlStyle}"/>
</StackPanel>
</Grid>
Related
I have the following WPF control containing a Data Visualization Chart (while this is the C# code behind it). My problem is that whatever I try, I can't change the tooltips of the points.
I tried looking for other quests and I saw different kind of solutions. One kind assigned an certain event to the chart, but my LineChart doesn't have these events. I tried adding a template, but nothing happen (I still see the same tooltip)
<DVC:Chart Canvas.Top="80" Canvas.Left="10" x:Name="LineChart" Title="Linea" Foreground="Black" Background="{DynamicResource Brush09}" BorderBrush="Transparent" PlotAreaStyle="{DynamicResource GridStyle1}" Margin="0,5,0,0">
<DVC:Chart.TitleStyle>
<Style TargetType="{x:Type DV:Title}">
<Setter Property="FontSize" Value="15" />
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</DVC:Chart.TitleStyle>
<DVC:Chart.LegendStyle>
<Style TargetType="{x:Type DV:Legend}">
<Setter Property="FontSize" Value="10" />
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="Margin" Value="15,0"/>
<Setter Property="Width" Value="{Binding LegendVisibility, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="BorderBrush" Value="{DynamicResource Brush09}"/>
<Setter Property="Foreground" Value="{StaticResource Brush08}" />
<Setter Property="Background" Value="{DynamicResource Brush09}" />
<Setter Property="Visibility" Value="Collapsed" />
</Style>
</DVC:Chart.LegendStyle>
<DVC:Chart.Axes>
<DVC:DateTimeAxis x:Name="xAxis" Orientation="X" Foreground="Black" FontFamily="Segoe UI" FontSize="10"/>
<DVC:LinearAxis x:Name="yAxis" Orientation="Y" Minimum="0" Foreground="Black" FontFamily="Segoe UI" FontSize="10">
</DVC:LinearAxis>
</DVC:Chart.Axes>
<DVC:LineSeries x:Name="SeriesColumn" DependentValuePath="Value" IndependentValuePath="Key" ItemsSource="{Binding}" DataContext="{Binding}" Margin="0">
<DVC:LineSeries.Background>
<RadialGradientBrush Center="0.075,0.015" GradientOrigin="-0.1,-0.1" RadiusY="0.9" RadiusX="1.05">
<GradientStop Color="#FFB9D6F7"/>
<GradientStop Color="#FF284B70" Offset="1"/>
</RadialGradientBrush>
</DVC:LineSeries.Background>
</DVC:LineSeries>
</DVC:Chart>
What I want is the following result. I want to keep all my values as double, but I want the tooltip to show "number+s" if the value is less then 60, while I want to see "number+m number+s" if the number is greater then 60. Is it possible?
I have some buttons -in different windows- that have the same content. But if two windows surfaced together,out of the first window's button content disappears.
Buttons Style is :
<Style TargetType="{x:Type Button}" x:Key="BSaveBtn">
<Setter Property="Padding" Value="5"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Width" Value="70"/>
<Setter Property="Height" Value="68"/>
<Setter Property="Background" Value="{DynamicResource FlatGreen}"/>
<Setter Property="Template" Value="{DynamicResource FlatGreenBtnHover}"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Vertical" FlowDirection="RightToLeft">
<Image Width="30" Source="/login;component/img/buttonpic/save.png"/>
<TextBlock Text="save" FontSize="16" FontFamily="/login;component/fonts/#Droid Arabic Kufi" Foreground="White" HorizontalAlignment="Center"/>
</StackPanel>
</Setter.Value>
</Setter>
</Style>
button Code in windows is :
<Button Style="{DynamicResource BSaveBtn}" Template="{DynamicResource FlatGreenBtnHover}" />
problems occurs only with content -not another style properties- .
Seems to work fine for me when I tested it here.
A few things I noticed though that may help. You don't need them to be DynamicResource, they should really be StaticResource unless you plan on modifying them.
I assume you are declaring these in the Windows.Resource section or repeating them on each window?
If so you should centralize those to a ResourceDictionary.
Create a new Resource Dictionary put your style in there like so:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type Button}" x:Key="BSaveBtn">
<Setter Property="Padding" Value="5"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Width" Value="70"/>
<Setter Property="Height" Value="68"/>
<Setter Property="Background" Value="{DynamicResource FlatGreen}"/>
<Setter Property="Template" Value="{DynamicResource FlatGreenBtnHover}"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Vertical" FlowDirection="RightToLeft">
<Image Width="30" Source="/login;component/img/buttonpic/save.png"/>
<TextBlock Text="save" FontSize="16" FontFamily="/login;component/fonts/#Droid Arabic Kufi" Foreground="White" HorizontalAlignment="Center"/>
</StackPanel>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Then in your App.xaml put the following:
<ResourceDictionary>
<ResourceDictionary Source="MyResources.xaml" />
</ResourceDictionary>
The Image should really be in a dictionary to avoid loading it multiple times. Just add a line in that ResourceDictionary like so:
<BitmapImage UriSource="/login;component/Images/Save.png" x:Key="Save" PresentationOptions:Freeze="True" />
Setting the PresentationOptions:Freeze will also help if the image is never being modified.
Your call to the image would then change to be:
<StackPanel Orientation="Vertical" FlowDirection="RightToLeft">
<Image Width="30" Source="{StaticResource Save}"/>
<TextBlock Text="save" FontSize="16" FontFamily="/login;component/fonts/#Droid Arabic Kufi" Foreground="White" HorizontalAlignment="Center"/>
</StackPanel>
Once your resources are centralized in a ResourceDictionary (or multiple) it makes it easy to apply those same styles anywhere in your application and hopefully will help with your issue. If not please give more info on the problem you have such as sample code to make the issue happen please.
An instance of an element can only appear once in the visual tree. You can set the x:Shared attribute of the Style to False in order for a new instance of the StackPanel to get created for each Button to which you apply the style:
<Style TargetType="{x:Type Button}" x:Key="BSaveBtn" x:Shared="False">
<Setter Property="Padding" Value="5"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Width" Value="70"/>
<Setter Property="Height" Value="68"/>
<Setter Property="Background" Value="{DynamicResource FlatGreen}"/>
<Setter Property="Template" Value="{DynamicResource FlatGreenBtnHover}"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Vertical" FlowDirection="RightToLeft">
<Image Width="30" Source="/login;component/img/buttonpic/save.png"/>
<TextBlock Text="save" FontSize="16" FontFamily="/login;component/fonts/#Droid Arabic Kufi" Foreground="White" HorizontalAlignment="Center"/>
</StackPanel>
</Setter.Value>
</Setter>
</Style>
I am using a TextBox like this:
<TextBox x:Name="TxtName" IsEnabled="False" Header="Textbox header" IsReadOnly="True" TextWrapping="Wrap" Text="{Binding Name,Mode=TwoWay}" Style="{StaticResource MyTextBoxStyle}" />
I would like to be able to style (i.e. setting the font) the Header of the TextBox in a ResourceDictionary. When I set the FontFamily of the TextBox it also affect the header, but I would like to set two different font styles for the text inside the TextBox and the text in the Header.
This is my style for the TextBox:
<Style x:Key="MyTextBoxStyle" TargetType="TextBox">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="FontFamily" Value="Comic Sans MS" />
</Style>
How can I do this?
Try This
<TextBox Height="70" Width="200" Text="Text" Foreground="Green" FontFamily="Tahoma">
<TextBox.Header>
<TextBlock Text="Header" Foreground="red" FontFamily="Times New Roman"></TextBlock>
</TextBox.Header>
</TextBox>
Update
<Page.Resources>
<Style TargetType="TextBox">
<Setter Property="Height" Value="70"></Setter>
<Setter Property="Width" Value="200"></Setter>
<Setter Property="Text" Value="Text"></Setter>
<Setter Property="FontFamily" Value="Tahoma"></Setter>
<Setter Property="Foreground" Value="Green"></Setter>
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Foreground="Red" Text="{Binding}" FontFamily="Times New Roman"></TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<TextBox Header="Header" />
I have a list view which is data bound to a class called FolderItem. I simply set the DataContext in the code behind.
Based on certain conditions I want to disable certain ListViewItems so that it cannot be selected. Do I have to drill down the tree to obtain the items I want to disable? If so, any links or pointers as to how to do it would be helpful. Or is there any other way to do this?
EDIT
<ListView x:Name="FolderListView" ItemsSource="{Binding}" ItemContainerStyle="{StaticResource ListViewItemStyle1}" SelectionChanged="SelectionChanged" IsTapEnabled="True" SelectionMode="Single" AllowDrop="False" CanDragItems="False" IsSwipeEnabled="False">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="60" Width="380" Margin="0,0,0,1" >
<Grid x:Name="ItemGrid" HorizontalAlignment="Left" VerticalAlignment="Center" Width="380" Height="60" >
<TextBlock x:Name="titleTextBlock" Foreground="Black" Text="{Binding FolderText}" Margin="20,0,0,0" VerticalAlignment="Center" TextAlignment="Left" FontSize="25" >
</TextBlock>
</Grid>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
This is the ListViewItemStyle1
<Style x:Key="ListViewItemStyle1" TargetType="ListViewItem">
<Setter Property="IsEnabled" Value="{Binding IsItemEnabled}"/>
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
<Setter Property="Background" Value="{Binding ItemBgBrush}"/>
<Setter Property="TabNavigation" Value="Local"/>
<Setter Property="IsHoldingEnabled" Value="False"/>
<Setter Property="Margin" Value="{ThemeResource ListViewItemMargin}"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
</<Style>
I have bound IsEnabled property with class. But it seem to have no effect. Is it because I have defined <ListView.ItemTemplate>??
I have a ListView that is using a DataTemplate. I swap out the Item DataTemplate based on the IsSelected property of the particular item. This allows me to display an edit template and a read template. The ListView contains two columns. In read mode the two columns are readonly TextBoxes and in edit mode the left column is a editable TextBox and the right column is a drop down. Everything works great as long as I don't click directly on one of the TextBoxes when in read mode. If I click outside the control the row is selected just fine, when selecting inside the control, however, the row is not selected. This prevents me from entering edit mode when one of the cells are clicked.
I've pasted my xaml below. You can see that the GridBlock and GridEdit styles will be controlled by the IsSelected property of the ListView. This is what allows me to swap out the DataTemplate (really hide or collapse) based on that DP. I've further specialized these styles to allow for watermarked textboxes when the value is empty and the control doesn't have focus. I think this is where my problem lies but for the life of me I can't think of a way to do this declaratively. Also, I'm new to WPF so I'm sure there is a pattern for this sort of thing it's just very difficult to formulate a query that will return meaningful results from google or bing. Thanks for any and all help in advance.
Here are my styles and datatemplates:
<Style TargetType="{x:Type FrameworkElement}" x:Key="GridBlockStyle">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Visibility"
Value="{Binding Path=IsSelected,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ListViewItem}},
Converter={StaticResource boolToVis},
ConverterParameter=False}" />
</Style>
<Style TargetType="{x:Type FrameworkElement}" x:Key="GridEditStyle">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Visibility"
Value="{Binding Path=IsSelected,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ListViewItem}},
Converter={StaticResource boolToVis},
ConverterParameter=True}" />
</Style>
<Style x:Key="TextBoxReadOnly" TargetType="{x:Type TextBox}" BasedOn="{StaticResource GridBlockStyle}">
<Setter Property="KeyboardNavigation.TabNavigation" Value="None" />
<Setter Property="AllowDrop" Value="true" />
<Setter Property="Background" Value="Transparent"></Setter>
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="Padding" Value="8,5,3,3" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Label x:Name="TextPrompt" Content="{TemplateBinding Tag}" Visibility="Collapsed" Focusable="False" Foreground="Silver"></Label>
<ScrollViewer Margin="0" x:Name="PART_ContentHost" Foreground="{DynamicResource OutsideFontColor}" />
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsFocused" Value="False"></Condition>
<Condition Property="Text" Value=""></Condition>
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Visibility" TargetName="TextPrompt" Value="Visible"></Setter>
</MultiTrigger.Setters>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="DimGray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="TextBoxEditable" TargetType="{x:Type TextBox}" BasedOn="{StaticResource GridEditStyle}">
<Setter Property="KeyboardNavigation.TabNavigation" Value="None" />
<Setter Property="AllowDrop" Value="true" />
<Setter Property="Background" Value="Transparent"></Setter>
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="Padding" Value="8,5,3,3" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Border x:Name="BorderBase" Background="White" BorderThickness="1.4,1.4,1,1"
BorderBrush="Silver" />
<Label x:Name="TextPrompt" Content="{TemplateBinding Tag}" Visibility="Collapsed" Focusable="False" Foreground="Silver"></Label>
<ScrollViewer Margin="0" x:Name="PART_ContentHost" Foreground="{DynamicResource OutsideFontColor}" />
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsFocused" Value="False"></Condition>
<Condition Property="Text" Value=""></Condition>
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Visibility" TargetName="TextPrompt" Value="Visible"></Setter>
</MultiTrigger.Setters>
</MultiTrigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="BorderThickness" TargetName="BorderBase" Value="2.4,2.4,1,1"></Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="DimGray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And here is my ListView view:
<ListView.View>
<GridView>
<GridViewColumn Width="120">
<GridViewColumnHeader Content="Resource ID" />
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<TextBox Margin="3" Tag="Enter Resource ID" Text="{Binding Path=ResourceID, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource TextBoxReadOnly}" IsReadOnly="True" />
<TextBox Width="90" Tag="Enter Resource ID" Margin="3"
Style="{StaticResource TextBoxEditable}" Text="{Binding Path=ResourceID, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="120">
<GridViewColumnHeader Content="Code" />
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<TextBox Margin="3" Tag="Enter Code" Text="{Binding Path=Code}"
Style="{StaticResource TextBoxReadOnly}" IsReadOnly="True" />
<ComboBox Margin="3" Style="{StaticResource GridEditStyle}"
ItemsSource="{Binding Source={StaticResource CodeViewSource}, Mode=OneWay}"
SelectedItem="{Binding Path=Code, Mode=TwoWay}"
IsSynchronizedWithCurrentItem="False"
util:ComboBoxWidthFromItemsBehavior.ComboBoxWidthFromItems="True" />
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="120">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Margin="5" Content="Delete"
Command="{Binding Path=DataContext.RemoveORIEntryCommand,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type UserControl}}}">
<Button.Resources>
<Converter:AgencyItemIDParametersConverter x:Key="RemoveListViewItemParametersConverter" />
</Button.Resources>
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource RemoveListViewItemParametersConverter}">
<MultiBinding.Bindings>
<Binding Path="AgencyID" />
<Binding Path="ID" />
</MultiBinding.Bindings>
</MultiBinding>
</Button.CommandParameter>
</Button>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
I had a similar problem in a ListView.
Basically each item of the ListView had a RadioButton and a TextBox. The RadioButton IsChecked property was binded to the ListViewItem select property. The thing was that when I selected the TextBox the item was not selected, hence not checking the RadioButton.
I managed to solve the problem with the IsKeyboardFocusWithin property. I set a trigger in the ListViewItem style so when this property is true the isSelected property would be set to true also.
You can check this thread.