I'm using wpf datagrid, and I'm using grouping to group my orders by number of order, and I also have a status for each order item, like : is it proceed or not, but somehow it looks messy on screen if I list each status for each item, because if one item of each order is proceed that means all of items are also proceed, so I'm wondering is it possible to move status next to Order number (Expander header - DockPanel) so I might get look like this:
Order number :# 1 - Order is in progress.
Order number :# 2 - Order is in progress.
Order number :# 3 - Order is not in progress.
So question is:
IS IT POSSIBLE TO MOVE 'ORDER STATUS' NEXT TO Order Number part?:)
Here is my code:
<DataGrid.GroupStyle>
<!-- Style for groups at top level. -->
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True" Background="Black" Opacity="0.7">
<Expander.Header >
<DockPanel Height="50" Margin="0,0,0,0" Name="dockPanel" Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}, Path=ActualWidth}">
<Button Name="btnFinishOrder" Content="Finish order" Margin="0,0,55,5" DockPanel.Dock="Right" Click="btnFinishOrder_Click" FontSize="12" BorderThickness="1.5" HorizontalAlignment="Left" VerticalAlignment="Bottom" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="#83D744" Background="Transparent" BorderBrush="#83D744" Width="130" Height="40">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<Button Name="btnTakeIt" Click="btnTakeIt_Click" Content="Take it!" Margin="0,0,20,5" DockPanel.Dock="Right" FontSize="12" BorderThickness="1.5" HorizontalAlignment="Left" VerticalAlignment="Bottom" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="#83D744" Background="Transparent" BorderBrush="#83D744" Width="130" Height="40">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<TextBlock FontWeight="Normal" FontFamily="Verdana" FontSize="20" Height="25" Foreground="#83D744" Text="{Binding Path=Name,StringFormat= Order Number:# {0}}" />
</DockPanel>
</Expander.Header>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
</DataGrid>
code behind:
public partial class MainWindow : Window
{
CollectionViewSource collectionViewSource = new CollectionViewSource();
public MainWindow()
{
try
{
InitializeComponent();
this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
this.WindowState = WindowState.Maximized;
var ordersList = OrdersController.localOrders();
collectionViewSource.Source = ordersList;
collectionViewSource.GroupDescriptions.Add(new PropertyGroupDescription("NumberOfOrder"));
DataContext = collectionViewSource;
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1000);
timer.Tick += timer_Tick;
timer.Start();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
The Expander.Header does not get one of your view models as DataContext. Instead the header gets an object that inherits from CollectionViewGroup. One of its properties is Name. That's why you can bind to Name in your XAML
<TextBlock ... Text="{Binding Path=Name,StringFormat= Order Number:# {0}}" />
Another property of interest is Items. That's the list of all view models of that group. Now it's easy to access an item's property in the header
<TextBlock ... Text="{Binding Path=Items[0].MyProperty}" />
Related
it's my first question here so be gentle haha
I am using a WPF TextBox Element to enter some user information, in this example it's a username.
My problem with this is that I am able to scroll within the TextBox which I don't want, as it just looks terrible even if it is just a bit.
So I am looking for an option to turn the scrolling off. As you can see I am using a ScrollViewer, as the documentation suggests but if there are any other options for styling the TextBox I am more then willing to try :D
Thanks in advance.
<Style TargetType="{x:Type TextBox}"
x:Key="textBox1">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border CornerRadius="16"
Background="{TemplateBinding Background}">
<ScrollViewer Margin="10,7.5"
x:Name="PART_ContentHost"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
=> This is the Style of the TextBox in a RessourceDic.
<StackPanel Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2">
<Grid Height="250"/>
<TextBlock x:Name="Error"
FontSize="14"
Foreground="DarkRed"
FontWeight="Bold"
Margin="5"
TextWrapping="Wrap"/>
<TextBlock Text="Benutzername" Margin="15,0,0,10" FontSize="20"/>
<TextBox Margin="0,0,20,0"
Background="#F2E3D5"
x:Name="Username"
Style="{StaticResource textBox1}"
Width="230"
Height="35"
FontSize="21">
</TextBox>
<TextBlock Text="Passwort" Margin="15,20,0,10" FontSize="20"/>
<PasswordBox Margin="0,0,20,0"
Background="#F2E3D5"
x:Name="Password"
Style="{StaticResource passwordBox1}"
FontSize="21">
</PasswordBox>
<Button x:Name="LogIn" Height="40" Width="120" Style="{StaticResource LogInBTN}" Foreground="Black" Margin="0,30,0,0" Click="LogInBTN_Click">
<Button.Content>
<StackPanel Orientation="Horizontal">
<Image Source="images/user.png" Height="25" Width="25" VerticalAlignment="Center"/>
<TextBlock Text="Einloggen" Margin="10,2,0,0" VerticalAlignment="Center"/>
</StackPanel>
</Button.Content>
</Button>
<TextBlock Margin="0,20,0,0" Height="20" Width="250" Text="X - Passwort nicht korrekt" TextAlignment="Center" FontSize="16" Foreground="Red" Visibility="Hidden"/>
</StackPanel>
=> This is the Stackpanel where I use the TextBox.
as workaround, without overriding ScrollViewer:
<TextBox Height="30" Width="50">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<Decorator x:Name="PART_ContentHost"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TextBox.Style>
</TextBox>
hi i want to change the default mouse over color of ListViewItems in WPF and i tried this code to change the default mouse over color here is my code
<ListView x:Name="lv"
Background="Transparent"
BorderBrush="Transparent"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Margin="0,20,0,0"
>
<!--home-->
<ListViewItem HorizontalAlignment="Left"
Style="{StaticResource lv_font}"
Height="60" MouseEnter="ListViewItem_MouseEnter"
>
<StackPanel Orientation="Horizontal"
Width="230"
Margin="-6,0,0,0"
Height="60"
>
<Image Source="/Assert/alarms_home.ico"
Stretch="None"
Margin="7,0,0,0"
VerticalAlignment="Center"
/>
<TextBlock Text="خانه"
Margin="50,0,0,0"
VerticalAlignment="Center"
/>
</StackPanel>
<!--tooltip-->
<ListViewItem.ToolTip>
<ToolTip x:Name="tt_home"
Content="خانه"
Style="{StaticResource tt_style}"/>
</ListViewItem.ToolTip>
</ListViewItem>
<!--alarms-->
<ListViewItem HorizontalAlignment="Left"
Style="{StaticResource lv_font}"
Margin="0,20,0,0"
Height="60"
MouseEnter="ListViewItem_MouseEnter"
>
<StackPanel Orientation="Horizontal"
Width="230"
Margin="-6,0,0,0"
Height="60"
>
<Image Source="/Assert/icons8_alarm_on_1.ico"
Stretch="None"
Margin="7,0,0,0"
VerticalAlignment="Center"/>
<TextBlock Text="یادداشت ها"
Margin="50,0,0,0"
VerticalAlignment="Center"
/>
</StackPanel>
<!--tooltip-->
<ListViewItem.ToolTip>
<ToolTip x:Name="tt_alarms"
Content="یادداشت ها"
Style="{StaticResource tt_style}"/>
</ListViewItem.ToolTip>
</ListViewItem>
<!--add notes-->
<ListViewItem HorizontalAlignment="Left"
Style="{StaticResource lv_font}"
Margin="0,20,0,0"
Height="60"
MouseEnter="ListViewItem_MouseEnter"
>
<StackPanel Orientation="Horizontal"
Width="230"
Margin="-6,0,0,0"
Height="60"
>
<Image Source="/Assert/alarm_add_1.ico"
Stretch="None"
Margin="7,0,0,0"
VerticalAlignment="Center"/>
<TextBlock Text="افزودن"
Margin="50,0,0,0"
VerticalAlignment="Center"
/>
</StackPanel>
<!--tooltip-->
<ListViewItem.ToolTip>
<ToolTip x:Name="tt_add"
Content="افزودن"
Style="{StaticResource tt_style}"/>
</ListViewItem.ToolTip>
</ListViewItem>
<!--about us-->
<ListViewItem HorizontalAlignment="Left"
Style="{StaticResource lv_font}"
Margin="0,20,0,0"
Height="60"
MouseEnter="ListViewItem_MouseEnter"
>
<StackPanel Orientation="Horizontal"
Width="230"
Margin="-6,0,0,0"
Height="60"
>
<Image Source="/Assert/icons8_about_5.ico"
Stretch="None"
Margin="7,0,0,0"
VerticalAlignment="Center"
/>
<TextBlock Text="درباره ما"
Margin="50,0,0,0"
VerticalAlignment="Center"
/>
</StackPanel>
<!--tooltip-->
<ListViewItem.ToolTip>
<ToolTip x:Name="tt_about"
Content="درباره ما"
Style="{StaticResource tt_style}"/>
</ListViewItem.ToolTip>
</ListViewItem>
<!--style-mouse-over for list-->
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border x:Name="Bd1"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="True"
>
<ContentPresenter
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
/>
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver"
Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Background"
TargetName="Bd1"
Value="#B5C1B4"/>
<Setter Property="BorderBrush"
TargetName="Bd1"
Value="#B5C1B4"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
But it is not worked, I did not get any error but it is not changed the default color if you have any other idea or this code is wrong please tell me.
Thanks
I have created a style that creates a Label as a circle with the text in the middle.
<Style x:Key="RoundedLabelStyle" TargetType="{x:Type Label}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Label">
<Grid Height="Auto" Width="Auto" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
<Ellipse x:Name="cp" Margin="0,0,0,0" Fill="{TemplateBinding Background}" Height="{TemplateBinding Width}" Width="{TemplateBinding Width}" Stroke="Black" StrokeThickness="2" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center">
<ContentPresenter.Content>
<Border Padding="10">
<ContentPresenter Content="{TemplateBinding Content}"/>
</Border>
</ContentPresenter.Content>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Its used in this way:
<Label Style="{StaticResource RoundedButtonStyle}" Content="{Binding CountValue}" HorizontalAlignment="Center" VerticalAlignment="Center" Background="Red" BorderBrush="Red" BorderThickness="3" Height="100" Width="100" FontSize="20" FontWeight="Bold" />
This works fine.
However I want to add further information to this label by having two text fields in different locations.
The first one already exists and displays in the centre of the ellipse.
Id like to add one which displays underneath the Ellipse.
Id like to be able to implement it in pure xaml if it is possible and use it something like this where the binding to SecondLabelText shows under the Ellipse:
<Label Style="{StaticResource RoundedButtonStyle}" Content="{Binding CountValue}" SecondContent="{Binding SecondLabelText}" HorizontalAlignment="Center" VerticalAlignment="Center" Background="Red" BorderBrush="Red" BorderThickness="3" Height="100" Width="100" FontSize="20" FontWeight="Bold" />
I can add the label into the style, but how do i set two separate contents?
Don't know if this is any use to you; went away and created this as a custom user control as a bit of a practice, You can create a new user control, setting 2 properties to receive the 2 contents:
using System.Windows;
using System.Windows.Controls;
namespace Custom_Control_Elipse_2_labels
{
/// <summary>
/// Interaction logic for EllipseWithTwoLabels.xaml
/// </summary>
public partial class EllipseWithTwoLabels : UserControl
{
public static readonly DependencyProperty Content1Property = DependencyProperty.Register("Content1", typeof(string), typeof(EllipseWithTwoLabels));
public static readonly DependencyProperty Content2Property = DependencyProperty.Register("Content2", typeof(string), typeof(EllipseWithTwoLabels));
public EllipseWithTwoLabels()
{
InitializeComponent();
DataContext = this;
}
public string Content1
{
get => (string) GetValue(Content1Property);
set => SetValue(Content1Property,value);
}
public string Content2
{
get => (string)GetValue(Content2Property);
set => SetValue(Content2Property, value);
}
}
}
The .xaml for the user control being
<Grid>
<Label Content="{Binding Content1}" Style="{StaticResource RoundedButtonStyle}" HorizontalAlignment="Center" VerticalAlignment="Center" Background="Red" BorderBrush="Red" BorderThickness="3" Height="100" Width="100" FontSize="20" FontWeight="Bold" ></Label>
<Label Content="{Binding Content2}" Margin="0,150,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" ></Label>
</Grid>
You can then just import it into any view to use it with: (
xmlns:local="clr-namespace:Custom_Control_Elipse_2_labels"
And use with the xaml:
<local:EllipseWithTwoLabels Height="300" Width="300" Content1="Content #1" Content2="Content #2"/>
Is one way to get it done :)
It provides something like this:
You can use for example Tag property of label to store extra data
<Label Style="{StaticResource RoundedLabelStyle}" Content="Content" Tag="Content#2"/>
In template just bind to Tag property
<ContentPresenter Content="{TemplateBinding Tag}"/>
Better approach is to use AttachedProperty. This allow you declare as many extra content as you want, without creating new type of control
public class LabelExtension
{
public static readonly DependencyProperty SecondContentProperty = DependencyProperty.RegisterAttached(
"SecondContent", typeof(object), typeof(LabelExtension));
public static void SetSecondContent(UIElement element, object value)
{
element.SetValue(SecondContentProperty, value);
}
public static object GetSecondContent(UIElement element)
{
return (object)element.GetValue(SecondContentProperty);
}
}
Set it on control
<Label Style="{StaticResource RoundedLabelStyle}" Content="Content" local:LabelExtension.SecondContent="Content#2"/>
Use from within template
<ContentPresenter Content="{TemplateBinding local:LabelExtension.SecondContent}"/>
Complete label style example
<Style x:Key="RoundedLabelStyle" TargetType="{x:Type Label}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Label">
<Grid Height="Auto" Width="Auto" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
<Ellipse x:Name="cp" Margin="0,0,0,0" Fill="{TemplateBinding Background}" Height="{TemplateBinding Width}" Width="{TemplateBinding Width}" Stroke="Black" StrokeThickness="2" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center">
<ContentPresenter.Content>
<Border Padding="10">
<StackPanel>
<ContentPresenter Content="{TemplateBinding Content}"/>
<ContentPresenter Content="{TemplateBinding Tag}"/>
<ContentPresenter Content="{TemplateBinding local:LabelExtension.SecondContent}"/>
</StackPanel>
</Border>
</ContentPresenter.Content>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I have applied a custom style to my DataGrid's column headers. Here is a simplified version of it:
<Style x:Key="DataGridColumnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridColumnHeader">
<Grid>
<Border BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
<Grid>
<StackPanel Orientation="Horizontal">
<ContentPresenter Margin="5 0 5 0" HorizontalAlignment="Center" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<Image IsHitTestVisible="True" Source="pin.png">
<Image.InputBindings>
<MouseBinding MouseAction="LeftClick" Command="{x:Static myView:MyCommand}" CommandParameter="{Binding}" />
</Image.InputBindings>
</Image>
</StackPanel>
</Grid>
</Border>
<Thumb x:Name="PART_LeftHeaderGripper" Style="{StaticResource DataGridColumnHeaderResizeThumb}"/>
<Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" Style="{StaticResource DataGridColumnHeaderResizeThumb}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I am struggling to get the command to fire when clicking the image. Is there something I am missing? Is there a different way that I can fire a command when clicking an element (i.e. an image) within the DataGridColumnHeader?
Some more details:
MyCommand is defined in the Window's CommandBindings. I have not included this code here. I have other commands defined similarly for other elements (i.e. DataGridCell) that work OK. It seems there is something specific to the way the DataGridColumnHeader element that prevents the command to be fired.
It seems like you're binding to the type MyCommand under xmlns myView; instead, you should be binding to an instance of MyCommand (assuming class MyCommand implements ICommand). You may consider implementing singleton here. Or you could define a static instance of MyCommand anywhere.
How to access a named control that is in the content template of the contentpresenter. how to access the webview control(x:name=detView) from cs file.
<ContentPresenter
x:Name="DetailContentPresenter"
Grid.Row="0"
BorderBrush="{ThemeResource SystemControlForegroundBaseLowBrush}"
Content="{x:Bind coll.SelectedItem,Mode=OneWay}">
<ContentPresenter.ContentTemplate>
<DataTemplate x:DataType="data:coll_Details" x:Name="ttt">
<Grid>
<WebView DefaultBackgroundColor="#F5F5F5" x:Name="detView" Source="ms-appx-web:///Assets/Web/collDetails.html"/>
</Grid>
</DataTemplate>
</ContentPresenter.ContentTemplate>
<ContentPresenter.ContentTransitions>
<TransitionCollection/>
</ContentPresenter.ContentTransitions>
</ContentPresenter>
If you are using ContentPresenter as ControlTemplate like the example of Official Documentation.
You can get the template through the controlName.ContentTemplateRoot. I made a demo from the Example of official documentation above, and put a webview inside the DataTemplate.
MainPage.xaml:
<Page.Resources>
<Style TargetType="HyperlinkButton" x:Key="myStyle" >
...
<Setter Property="Template" x:Name="presenterSetter">
<Setter.Value>
<ControlTemplate TargetType="HyperlinkButton">
<Grid x:Name="rootGrid">
...
<Border x:Name="Border"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Margin="3">
<ContentPresenter x:Name="MyContentPresenter"
Content="{TemplateBinding Content}"
ContentTransitions="{TemplateBinding ContentTransitions}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
>
<ContentPresenter.ContentTemplate>
<DataTemplate x:Name="ttt">
<Grid>
<WebView Source="ms-appx-web:///Assets/Web/default.html" Name="myWebView"/>
</Grid>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
</Border>
<!--focus visuals omitted-->
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel VerticalAlignment="Bottom">
<HyperlinkButton Name="myHyperlink" Style="{StaticResource myStyle}">This is a link</HyperlinkButton>
<Button Click="Button_Click" Name="myBtn">Click Me</Button>
</StackPanel>
</Grid>
And I can get the WebView using the codes below:
private void Button_Click(object sender, RoutedEventArgs e)
{
var myView= ((Grid)myHyperlink.ContentTemplateRoot).Children[0] as WebView;
}
In C#, use this code to find any control which is present in your ContentPresenter.
If a TextBlock is present in your ContentPresenter then first create a object of the TextBlock then cast it and then find control.
TextBlock myTextBlock = (TextBlock)ttt.FindName(“textBlock”, DetailContentPresenter);