Diffrent style for first three rows of WPF ListView - wpf

I want the top three items in my ListView to have special style. How can i achieve this?
I have tried this but item is always null:
if (tracklistQueue.Items.Count > 0) {
ListViewItem item = (ListViewItem)tracklistQueue.ItemContainerGenerator.ContainerFromIndex(0);
item.Style = (Style)FindResource("StyleName");
}

You can use AlternationIndex and AlternationCount properties.
Following example sets different background color for first three rows.
Add this style definition to your UserControl (or Window):
<Style TargetType="ListViewItem">
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="#FFFF0000" />
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="#FF00FF00" />
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="2">
<Setter Property="Background" Value="#FF0000FF" />
</Trigger>
</Style.Triggers>
</Style>
Set AlternationCount of ListView to value which is greater than number of rows that ListView can actually contain:
<ListView AlternationCount="1000" />
Reference:
ItemsControl.AlternationCount Property

Solved it. The ItemContainerGenerator had not finished generating the items.
Added this to the constructor and put the code there:
this.tracklistQueue.ItemContainerGenerator.StatusChanged += new EventHandler(ItemContainerGenerator_StatusChanged);

Related

WPF change tab header color

I am trying to set the tab color of the header when the tab is selected. I work with Mah:
<Style x:Key="MenuLevel2" BasedOn="{StaticResource MetroTabItem}" TargetType="{x:Type TabItem}">
<Setter Property="mah:ControlsHelper.HeaderFontSize" Value="20" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="SteelBlue"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<!-- Sould do the work -->
<Setter Property="Foreground" Value="SteelBlue"/>
</Trigger>
</Style.Triggers>
</Style>
The text of the header is unfortunately still the one from the theme color. Any clue?
Your problem lies in the Controls.TabControl.xaml of MahApps.Metro. Most of the design lies in a template. As you can see in line 227 and 274, the Foreground is not bound to any property like done with other properties like Underline or HeaderFontSize.
This means you can't style these properties explicit without creating a whole new template. Since dynamic resources are used as color a solution is to override the used resources. Here is a workaround to change the colors for a tab item like required:
<TabItem Header="TabItem1">
<TabItem.Resources>
<SolidColorBrush x:Key="AccentColorBrush" Color="SteelBlue"/>
<SolidColorBrush x:Key="HighlightBrush" Color="SteelBlue"/>
</TabItem.Resources>
</TabItem>

style the new row on datagrid (CanUserAddRows)

How can I change the new row style (of CanUserAddRows) I want the user to notice to the new row.
thanks
I've not tested this, but I think it should work. You can try adding some Style for the DataGridRow. Add some Trigger listening to IsNewItem. Then you can change almost everything related to the matched DataGridRow via the Trigger Setter. The following code will try highlighting the new row by setting a red border around it:
<DataGrid ItemsSource="someSource">
<DataGrid.Resources>
<Style TargetType="DataGridRow">
<Style.Triggers>
<Trigger Property="IsNewItem" Value="True">
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="2"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<!-- remaining code ... -->
</DataGrid>

TextBox Inside ListView WPF

I have a TextBox inside my ListView. When I click on the textview, the SelectionChanged event of ListView is not fired.
Is there a way to fire that, so that the ListView item is selected?
Despite the fact that you have not asked a good question, I think I understand your problem. I'm assuming that when you said textview, you actually meant Textbox and that your problem is that your ListViewItem is not changed to the item that contains the TextBox that you clicked on. If this is so, then adding this Style should do the trick:
<Style x:Key="ListViewItemSelectionStyle" TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="False">
<Setter Property="IsSelected" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
While it looks strange, the second part is to ensure that the item remains selected after it loses KeyboardFocus.
You haven't provided any code, but at a guess, you haven't handled the event:
<ListView SelectionChanged="MyEventHandler" ...
</ListView>

How to make a WPF DataGrid with alternating row colors, and a fix color section (ignoring alternation)

I have a datagrid that I'm trying to make resemble:
I'm using the AlternatingRowBackground attribute to perform the alternating colors. For the fixed color section, I have XAML that resembles:
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=ShouldBeFixedColor}" Value="True">
<DataTrigger.Setters>
<Setter Property="Background" Value="Blue" />
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
The problem with this approach is that the "alternating color" takes precedence over the fixed color style trigger. So, at the bottom instead of blue-blue-blue it is blue-gray-blue.
Any ideas on how to archive the desired coloring? I'd rather do this all at the XAML level if possible.
Thanks!
Made some changes based upon other SO answers. Hopefully this helps someone in the future.
Yank AlternatingRowBackground=... from the grid. Add AlternationCount="2"
Add the block below to do the styling (manually doing the alternating rows)
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<Trigger Property="AlternationIndex" Value="0">
<Setter Property="Background" Value="White" />
</Trigger>
<Trigger Property="AlternationIndex" Value="1">
<Setter Property="Background" Value="WhiteSmoke" />
</Trigger>
<DataTrigger Binding="{Binding Path=Selectable}" Value="False">
<DataTrigger.Setters>
<Setter Property="Background" Value="LightGray" />
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
In case someone else is also looking for the same thing done in code:
Style rowStyle = new Style(typeof(DataGridRow));
Trigger rowTrigger = new Trigger();
rowTrigger.Property = DataGridRow.AlternationIndexProperty;
rowTrigger.Value = 0;
Setter rowSetter = new Setter(DataGridRow.BackgroundProperty, Brushes.Yellow);
rowTrigger.Setters.Add(rowSetter);
Trigger alternateRowTrigger = new Trigger();
alternateRowTrigger.Property = DataGridRow.AlternationIndexProperty;
alternateRowTrigger.Value = 1;
Setter alternateRowSetter = new Setter(DataGridRow.BackgroundProperty, Brushes.Pink);
alternateRowTrigger.Setters.Add(alternateRowSetter);
DataTrigger rowDataTrigger = new DataTrigger();
rowDataTrigger.Value = true;
rowDataTrigger.Binding = new Binding() { Path = new PropertyPath(nameof(MyObject.IsSomethingTrue))};
Setter backgroundSetter = new Setter(DataGridRow.BackgroundProperty, Brushes.Blue);
Setter foregroundSetter = new Setter(DataGridRow.ForegroundProperty, Brushes.White);
rowDataTrigger.Setters.Add(backgroundSetter);
rowDataTrigger.Setters.Add(foregroundSetter);
// the order of the triggers may not be changed as explained by CptCoathanger
rowStyle.Triggers.Add(rowTrigger);
rowStyle.Triggers.Add(alternateRowTrigger);
rowStyle.Triggers.Add(rowDataTrigger);
RootDataGridOrders.RowStyle = rowStyle;

Unable to set Background property of MenuItem for IsPressed event

I want to change the background of a MenuItem when the MenuItem is pressed.
<Style x:Key="{x:Type MenuItem}" TargetType="MenuItem">
<Style.Triggers>
<Trigger Property="MenuItem.IsPressed" Value="True">
<Setter Property="MenuItem.Background" Value="#FFE389" />
<Setter Property="MenuItem.BorderBrush" Value="#C2762B" />
</Trigger>
</Style.Triggers>
</Style>
I tried doing the above, but the trigger does not seem to work. Is the Trigger wrong?
Update: It works for the event IsMouseOver but IsPressed does not seem to work
Update 2: It works for TopLevelMenuItems but does not work for TopLevelMenuHeaderItems.
Try this...which does not preface the property names with MenuItem and modify your TargetType and x:Key syntax...
<Style x:Key="MyStyle" TargetType="{x:Type MenuItem}">
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#FFE389" />
<Setter Property="BorderBrush" Value="#C2762B" />
</Trigger>
</Style.Triggers>
</Style>
EDIT:
Based on your updates take a look at how a default MenuItem is constructed via XAML. This should get you where you need to go in providing styling for the varying parts of the MenuItem. Note the use of the Role property within the MenuItem style dealing with the headers and items at both the top level and sub level.

Resources