how can i style only the header of a tree view ?
I want to make the header unselectable.
Something like:
<TreeViewHeaderStyle>
<Setter Property="Focusable" Value="false">
</TreeViewHeaderStyle>
Thank you :)
Style the TreeViewItem in your Window's or Control's resources.
<Window.Resources>
<Style TargetType="TreeViewItem">
<Setter Property="IsEnabled" Value="False"/>
</Style>
</Window.Resources>
EDIT:
If you still need to expand via the triangle, but want a disabled header, the solution is a bit dirtier. Many solutions show a complicated restyling of the HeaderedItemsControl you can search for that or simply add a Label to each TreeViewItem and handle a mouse down event. In the below example I wrapped a Label inside a grid so that I could style the label as needed. When the Grid is clicked the event is handled preventing expansion. If you are only setting the Label content, you can just add the MouseDown event to the Label and ditch the Grid.
<TreeViewItem>
<TreeViewItem.Header>
<Grid MouseDown="Grid_MouseDown">
<Label Content="TEST" IsEnabled="False" />
</Grid>
</TreeViewItem.Header>
<Button Content="Random SubItem"/>
</TreeViewItem>
CODE BEHIND:
private void Grid_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
e.Handled = true;
}
Related
I have created two user controls and I am planning to bind it inside a list view. In the main window I have a button and on the button click I am adding the first user control repeatedly. For that I created a observable collection of user controls and adding that to the list view. Currently that part is working well(On each button click first user control is adding to the list view properly). Now the requirement I have,
The list view can have usercontrol1 multiple time depends on the button click.
This user control have a button which will open usercontrol2.
Now the requirement I have, when I click the button from usercontrol1, user control one need to replace with usercontrol2. It is not about just replace, since the list view contain the usercontrol1 multiple times, if I click the nth usercontrol1, only that usercontrol1 need to replce with usercontrol2.
Since the description is bit confusing, Ienter image description here am adding an image which shows the idea and the code part how I bind usercontrol1 to the list view multiple time.
public ObservableCollection<UserControl> lis = new ObservableCollection<UserControl>();
private void NextScreen_Click(object sender, RoutedEventArgs e)
{
UserCntrl1 usr = new UserCntrl1();
ListView.ItemsSource = lis;
lis.Add(usr);
}
Adding a collection of UserControls to the ItemsSource property is wrong in the first place.
You should instead declare the UserControls in the ControlTemplate of the ListBoxItem. Switch between different templates by DataTriggers on a property in the data item class, like IsSelected in the example below. On Button click, change that property on the appropriate item.
<ListBox ItemsSource="{Binding Items}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<local:UserControl1 .../>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<local:UserControl2 .../>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
What I would recommend is using a TabControl with Collapsed TabItems and a navigation trigger via a Button. You can then easily place your page controls within each TabItem.
<Grid>
<TabControl x:Name="MainTabControl">
<TabItem Header="Page1" Visibility="Collapsed">
<StackPanel>
<Label Content="Page 1"/>
<Button Content="Next" Click="Page1_Button_Click"/>
</StackPanel>
</TabItem>
<TabItem Header="Page2" Visibility="Collapsed">
<Label Content="Page 2"/>
</TabItem>
</TabControl>
</Grid>
When the user clicks on the button the desired tab index is selected.
private void Page1_Button_Click(object sender, RoutedEventArgs e)
{
MainTabControl.SelectedIndex = 1;
}
I have a method that is supposed to color the background of a textbox that is on focus(Enter)
private void onEnter_ColourChange(object sender, EventArgs e)
{
this.BackColor = Color.White;
}
This doesn't work, however. I checked this answer, but I just got a NullReferenceException.
Essentially, I would like to color multiple textboxes when the textbox is in focus, with one method. Is there a way to do this?
First of all: TextBox has only the property Background and not BackColor!
If you want to change the color of the focused TextBox, a simple way is, to use a Style with a Trigger.
<Window.Resources>
<Style TargetType="TextBox" x:Key="TextBoxFocusBackgroundStyle" BasedOn="{StaticResource {x:Type TextBox}}">
<Style.Triggers>
<Trigger Property="IsFocused" Value="true" >
<Setter Property="Background" Value="Brown" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
As you can see, the Trigger watches on the property IsFocused. If the TextBox got the Focus (so IsFocused changes to true), the Background will be brown.
To use this Style:
<StackPanel>
<TextBox Text="Peter" Style="{StaticResource TextBoxFocusBackgroundStyle}"/>
<TextBox Text="Laszlo" Style="{StaticResource TextBoxFocusBackgroundStyle}"/>
<TextBox Text="Julia" Style="{StaticResource TextBoxFocusBackgroundStyle}"/>
<TextBox Text="Romeo" Style="{StaticResource TextBoxFocusBackgroundStyle}"/>
</StackPanel>
If you already has a Style for the TextBoxes you should use that Style in the BasedOn attribute.
I am running into a problem with WPF UI wherein I need to set the border of a GroupBox control based on the fact if there is any checkbox inside the GroupBox that has been unchecked. I have tried writing some code but that didn't work, I am new to WPF and I tried using a style to solve the problem but that didn't work well with me. The code looks as follows -:
<GroupBox Grid.Row="6" Grid.ColumnSpan="3" Header="View Actions" >
<GroupBox.Style>
<Style TargetType="GroupBox" d:DataContext="{d:DesignInstance ActionsViewModels:IActionViewModel}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsEnabled}" Value="False">
<Setter Property="BorderBrush" Value="Red" />
<Setter Property="BorderThickness" Value="2"/>
</DataTrigger>
</Style.Triggers>
</Style>
</GroupBox.Style>
<ContentControl Content="{Binding ViewActionsVM}"/>
</GroupBox>
Just FYI, the is used to populate the GroupBox with objects which have a text and checkbox component inside them and look something like this
Now what I want to be able to do is when one unchecks this checkbox I want to be able to add a red border around the Groupbox in which its contained. The content shown in the image comes from the ContentControl binding that we have in our project. To add to the description of the Content, the content describes an Action to be performed and has a property called as IsEnabled that I am using in the DataTrigger to decide whether to add a border or not.
I have this content dialog box defined inside my xaml:
<ContentDialog x:Name="AlertMessage" Background="#363636" IsSecondaryButtonEnabled="True" SecondaryButtonText="Cancel" IsPrimaryButtonEnabled="True" PrimaryButtonText="Ok" >
<ContentDialog.Content>
<StackPanel Name="rootStackPanel" Height="Auto" >
<StackPanel Margin="0">
<StackPanel Margin="0,0,0,10" Orientation="Horizontal">
<TextBlock x:Name="HeadingText" x:FieldModifier="public" Style="{StaticResource ApplicationMessageBoxHeadingStyle}" Text="Alert" />
<Image Margin="10,05,0,0" Source="/Assets/Images/alert.png" Width="35"></Image>
</StackPanel>
<TextBlock x:FieldModifier="public" x:Name="ContentText" Style="{StaticResource ApplicationMessageBoxErrorStyle}" Text="Are you sure you want to log off ?" />
</StackPanel>
</StackPanel>
</ContentDialog.Content>
</ContentDialog>
And I'm calling it like this:
private void AppBarButton_Click(object sender, RoutedEventArgs e)
{
MessageBox();
}
private async void MessageBox()
{
ContentDialogResult LogoutDialog = await AlertMessage.ShowAsync();
if (LogoutDialog == ContentDialogResult.Primary)
{
this.Frame.Navigate(typeof(MainPage));
}
else
{
// User pressed Cancel or the back arrow.
// Terms of use were not accepted.
}
}
Problem: is that my app have a style for all the buttons in my applications. And I want to apply same styles to the primary and secondary buttons of that dialog box too. And I am unable to figure out how to Achieve this. Is it possible to apply styles to these buttons?
I used this code to change Button color on my UWP app.
var cd = new ContentDialog();
cd.Content = "Remove file ?";
cd.Title = "Remove file";
cd.PrimaryButtonText = "OK";
cd.SecondaryButtonText = "Cancel";
var bst = new Windows.UI.Xaml.Style(typeof(Button));
bst.Setters.Add(new Setter(Button.BackgroundProperty, Colors.Red));
bst.Setters.Add(new Setter(Button.ForegroundProperty, Colors.White));
cd.PrimaryButtonStyle = bst;
var ress = await cd.ShowAsync();
You can indirectly customize the buttons.
The ContentDialog's buttons use the "default" style for the target type "Button". You can overwrite the ContentDialog Style of the SDK and add a different Button Style in the Setter of the Template. This button style will just be valid in the scope of the ContentDialog control.
In this example the new button style needs to be put in the first border element (x:Name="Container")
<Border.Resources>
<Style TargetType="Button" BasedOn="{StaticResource YourNormalButtonStyle}">
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="Foreground" Value="Red"/>
</Style>
</Border.Resources>
If you want to change the ContendDialog PrimaryButtonSettings you need inside ContenDialog.Resources just to set a Style that you are targeting Buttons and the Setter of With Property="" and Value="" and that should fix below is one example.
Converter={StaticResource StringEmptyToBoolConverter}}"
<ContentDialog.Resources>
<converters:StringEmptyToBoolConverter x:Key="StringEmptyToBoolConverter"/>
<Style TargetType="Button">
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="FontSize" Value="13.6"/>
<Setter Property="Width" Value="Auto"/>
</Style>
</ContentDialog.Resources>
<WebView Height="400" Width="500" DefaultBackgroundColor="Transparent" Source="{Binding State.GuideUri}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" x:Name="RulesWebView"/>
The ContentDialog buttons aren't customizable, but you can leave the ContentDialog's primary and secondary buttons unset and add your own buttons within the template.
I have a WPF app and I want to add an item with HorizontalAlignment = Left and then other with HorizontalAlignment = right, like a chat in Whatsapp, but all the text in the listbox have horizontal alignment on the right, How can I use different horizontal alignment in the same listbox.
This is my XAML code:
<ListBox x:Name="ListBoxChat" HorizontalAlignment="Stretch" Height="366" VerticalAlignment="Top" Width="270" Margin="2,44,0,0" Padding="2"/>
<TextBlock Foreground="Transparent" Name="TextB" Margin="2,-5,2,-3"></TextBlock>
and this is the C# code behind:
ListBoxChat.HorizontalAlignment = HorizontalAlignment.Left;
ListBoxChat.Items.Add("How are you ?");
ListBoxChat.HorizontalAlignment = HorizontalAlignment.Right;
ListBoxChat.Items.Add("Fine!!!");
Thank you!
You can create a single StackPanel to carry the ListView. Like this,
<StackPanel>
<ListView x:Name="chatList" Width="value" />
</StackPanel>
You don't really need the StackPanel, I just used it!
Now on the CSharp code, you can handle the events of the User or the Network. I won't go in the Depth of the process, but an example of that would be
void addItem (object sender, EventArgs e) {
// first create the new item!
ListViewItem item = new ListViewItem();
// add the properties..
item.Content = "Hi, my name is Slim Shady!";
if(messageBy == "user") {
// if message is by user, align it to right
item.HorizontalAlignment = HorizontalAlignment.Left;
} else {
// if message is by network (friend), align it to left
item.HorizontalAlignment = HorizontalAlignment.Right;
}
// now add the item to the listbox
chatList.Items.Add(item); // done! :-)
}
You can execute this code, each time there is new item to be appened! But you really need to make sure that the conditions are checked. Because using the Condition, you can change the color of the item too, like in WhatsApp, you can do other stuff too. It totally depends on the Condition, and the Way you use it.
Good luck!
You can achieve this by applying the style on your ListBoxItem and using AlternationCount and AlternationIndex as shown below:
<ListBox x:Name="ListBoxChat" HorizontalAlignment="Stretch" Height="366" VerticalAlignment="Top" Width="270" Margin="2,44,0,0" Padding="2"
AlternationCount="2">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(ItemsControl.AlternationIndex),
RelativeSource={RelativeSource Self}}" Value="0">
<Setter Property="HorizontalContentAlignment" Value="Left"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Path=(ItemsControl.AlternationIndex),
RelativeSource={RelativeSource Self}}" Value="1">
<Setter Property="HorizontalContentAlignment" Value="Right"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>