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>??
Related
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>
I have a simple list view.
<ListView x:Name="DatabasesLstVw" ItemsSource="{Binding Path=Issues}"
ItemContainerStyle="{StaticResource removeMouseOverStyle}"
AlternationCount="2" Grid.Row="1" Margin="20,10,20,0"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
FontSize="12" FontWeight="Normal"
BorderThickness="0" Background="Transparent"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.Resources>
<Style TargetType="GridViewColumnHeader">
<Setter Property="Visibility" Value="Collapsed" />
</Style>
</ListView.Resources>
<ListView.View>
<GridView >
<GridViewColumn Header="Message">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock TextWrapping="Wrap" Text="{Binding Name}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
I have created a style trying to remove the default mouse over and select styling.
<Style x:Key="removeMouseOverStyle" TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Transparent"></Setter>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Margin" Value="0,0,0,0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="FontSize" Value="12"/>
</Trigger>
<Trigger Property="ItemsControl.IsMouseOver" Value="true">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="FontWeight" Value="Normal"/>
</Trigger>
</Style.Triggers>
</Style>
I cant post what its doing without trying to create a gif picture of it. Basically its hopping a little with the mouse over. First I thought it was setting margin , then tried padding and font size.
What exactly is this default mouse over doing and how do I remove it?
There could be many ways how they could have implemented selection\mouse over. For example often it is done by showing separate Border for every state. For control such simple as ListViewItem it's better to override it's ControlTemplate and do what you need there. You can use default control template, just remove triggers:
<Style x:Key="removeMouseOverStyle"
TargetType="ListViewItem">
<Setter Property="SnapsToDevicePixels"
Value="true" />
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border Name="Border"
Padding="2"
SnapsToDevicePixels="true"
Background="Transparent">
<GridViewRowPresenter VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
With this style items won't change their appearence on selection or mouse over. Also, you can use base ItemsControl control - it does not have selection\mouse over behavior by default.
I'm still a little green when it comes to WPF. I'm currently working on a WPF form that has several text boxes on it. Each of those TextBoxes are paired with a TextBlock sitting in the same x,y coord, acting as GhostText. Once you click inside the TextBox the GhostText disappears.
Below is an example of how the binding was originally setup in the form's XAML (this same code is duplicated for all text boxes thus the reasoning behind using a style) :
<TextBox Grid.Column="0" Width="40" Height="25" VerticalAlignment="Top" HorizontalAlignment="Left" x:Name= "RecordMinutesTextBox" Padding="12,5,5,0" Text ="{Binding RecordMinute}" Margin="0,25,5,1" PreviewTextInput="CheckNumberValidation" Background="{Binding ElementName=FireWashingtonResponseTimeReport,Path=DataContext.RequiredFieldColor}"/>
<TextBlock Grid.Column="0" Width="40" IsHitTestVisible="False" Text="MIN" VerticalAlignment="Center" HorizontalAlignment="Left" Foreground="DarkGray" Margin="8,25,0,1" >
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Text, ElementName=RecordMinutesTextBox}" Value="">
<Setter Property="Visibility" Value="Visible"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
*Note the name of one of the many text boxes,"RecordMinutesTextBox", used as the ElementName for the DataTrigger Binding.
Here is the code from inside my WPF Style template:
<Style x:Key="MinuteAndSecondsGhostText" TargetType="TextBlock">
<Setter Property="Width" Value="40"/>
<Setter Property="IsHitTestVisible" Value="False"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Foreground" Value="DarkGray"/>
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Text, ElementName=??WhatDoIPutHere??}" Value="">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>enter code here
So my question really comes down to this. What should I use in the DataTrigger Binding as the ElementName for this style? Considering that I have multiple TextBoxes with different names on my form. Thanks in advance.
I give you an idea... and you can change your codes base on it.
In my following sample you see the TextBlock shows state of IsFocused property of the TextBox. So you can put the pair of your elements in a parent like StackPanel and access to properties of one child in another child by RelativeSource instead of ElementName...
Just put this codes in your window and focus in TextBox, What you see inside the TextBlock?
<StackPanel Orientation="Horizontal" Background="White" Margin="20">
<TextBox Text="" Name="TextBox" Background="DarkSalmon" Width="100" Height="30"/>
<TextBlock Text="{Binding Path=Children[0].IsFocused,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type StackPanel}}}"
Margin="20,0"/>
</StackPanel>
Edit:
Base on my above idea you can use RelativeSource instead of ElementName to resolve your problem like the following sample:
<Style x:Key="MinuteAndSecondsGhostText" TargetType="TextBlock">
<Setter Property="Width" Value="40"/>
<Setter Property="IsHitTestVisible" Value="False"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Foreground" Value="DarkGray"/>
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Children[0].Text,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type StackPanel}}}" Value="">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
And in your Window body:
<StackPanel x:Name="Pair1" Orientation="Horizontal" Background="White" Margin="20">
<!--TextBox should be first child of StackPanel-->
<TextBox Text="" Name="TextBox1" Background="DarkSalmon" Width="100" Height="30"/>
<TextBlock Text="Sample Text" Style="{StaticResource MinuteAndSecondsGhostText}" Margin="20,0"/>
</StackPanel>
<StackPanel x:Name="Pair2" Orientation="Horizontal" Background="White" Margin="20">
<!--TextBox should be first child of StackPanel-->
<TextBox Text="" Name="TextBox2" Background="DarkSalmon" Width="100" Height="30"/>
<TextBlock Text="Sample Text" Style="{StaticResource MinuteAndSecondsGhostText}" Margin="20,0"/>
</StackPanel>
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 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.