Accessing a control which is in a contentpresenter in c# - c#

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);

Related

How do I automatically expand my WPF tabitem to fit the header text?

enter image description here
Basically, this is what it looks like, I want my tabitem to automatically make the header text fit inside the tabitem. Thanks.
WPF tabitem widths are adaptive unless you specify a width. If you don't specify a width, check if you have fixed the width of the content control or container when you define the TabItem style.
<TabControl>
<TabItem Header="long"/>
<TabItem Header="longlonglonglong"/>
</TabControl>
Initial control template
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
<Border x:Name="mainBorder" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1" Margin="0">
<Border x:Name="innerBorder" Background="{StaticResource TabItem.Selected.Background}" BorderBrush="{StaticResource TabItem.Selected.Border}" BorderThickness="1" Margin="-1" Opacity="0"/>
</Border>
<ContentPresenter x:Name="contentPresenter" ContentSource="Header" Focusable="False" HorizontalAlignment="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
</Grid>
</ControlTemplate>

How to remove arrow from ColorCanvas dropdown control in wpf C#

I am using c# wpf ColorCanvas control for using colors in my application.I want to remove dropdown arrow from ColorCanvas control.
I am using this Xaml Code for ColorCanvas
<xctk:ColorPicker x:Name="canvas_Copy" ColorMode="ColorCanvas" VerticalAlignment="Top" Margin="93,323,409,0" />
For clarity check this image.I want to remove this Arrow form ColorCanvas.
You should use a custom ButtonStyle:
<xctk:ColorPicker x:Name="canvas_Copy" ColorMode="ColorCanvas" VerticalAlignment="Top" Margin="93,323,409,0" >
<xctk:ColorPicker.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</xctk:ColorPicker.Resources>
<xctk:ColorPicker.ButtonStyle>
<Style TargetType="ToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton" xmlns:chrome="clr-namespace:Xceed.Wpf.Toolkit.Chromes;assembly=Xceed.Wpf.Toolkit">
<Grid SnapsToDevicePixels="True">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="True">
<ContentPresenter Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" />
</Border>
<chrome:ButtonChrome x:Name="ToggleButtonChrome"
Grid.Column="1"
CornerRadius="0,2.75,2.75,0"
Visibility="{Binding ShowDropDownButton, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=xctk:ColorPicker}, Converter={StaticResource BooleanToVisibilityConverter}}"
RenderChecked="{Binding IsOpen, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=xctk:ColorPicker}}"
RenderEnabled="{Binding IsEnabled, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=xctk:ColorPicker}}"
RenderMouseOver="{TemplateBinding IsMouseOver}"
RenderPressed="{TemplateBinding IsPressed}">
</chrome:ButtonChrome>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</xctk:ColorPicker.ButtonStyle>
</xctk:ColorPicker>
Use ColorCanvas control from the same namespace instead of ColorPicker.
finds its css file (or its styling file) and change its color to match its background

Click element within Data Grid Column Header

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.

WPF DataGrid Dock panel grouping

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}" />

How to get control used in template in user control code?

How could I get a DataGrid control used in xaml style template to use it in code?
<UserControl>
<UserControl.Resources>
<Style x:Key="MyComboBoxStyle" TargetType="{x:Type ComboBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid x:Name="MainGrid" SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="0" MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" />
</Grid.ColumnDefinitions>
<Popup x:Name="PART_Popup"
Grid.ColumnSpan="2">
<Microsoft_Windows_Themes:SystemDropShadowChrome x:Name="Shdw">
<Border x:Name="DropDownBorder">
<DataGrid x:Name="PART_PopupDataGrid" />
</Border>
</Microsoft_Windows_Themes:SystemDropShadowChrome>
</Popup>
<ToggleButton Grid.ColumnSpan="2"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
IsChecked="{Binding Path=IsDropDownOpen,
Mode=TwoWay,
RelativeSource={RelativeSource TemplatedParent}}"
Style="{StaticResource ComboBoxReadonlyToggleButton}" />
<ContentPresenter Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
IsHitTestVisible="false"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid>
<ComboBox Name="ComboGrid" Style="{DynamicResource DataGridComboBoxStyle}" />
</Grid>
</UserControl>
There is how I tried to get DataGrid control in user control, but not successfully:
var v1 = this.FindName("PART_PopupDataGrid");
var v2 = this.Template.FindName("PART_PopupDataGrid", this);
var v3 = ComboGrid.FindName("PART_PopupDataGrid");
How could I get this control in code?
This is a very common requirement. In fact, it's so common that Microsoft even have a page on MSDN specifically for this:
How to: Find ControlTemplate-Generated Elements
Basically, if you have a reference to the ComboBox that the ControlTemplate is applied to (let's call it ComboBox), then you should be able to do this:
DataGrid dataGrid =
ComboBox.Template.FindName("PART_PopupDataGrid", ComboBox) as DataGrid;

Categories