How to get the absolute position of an element? - c#

Assume something simple like:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition Width="300" />
</Grid.ColumnDefinitions>
<TextBlock Name="MainTextBlock" Grid.Column="1" Text="Hello" />
</Grid>
How can I get the absolute position of MainTextBlock?

I think this will work...
var ttv = MainTextBlock.TransformToVisual(Window.Current.Content);
Point screenCoords = ttv.TransformPoint(new Point(0, 0));

Related

WPF - C# - Print a XAML Datagrid - multiplie Pages

XAML - Code:
<Grid Name="Label">
<Grid.RowDefinitions>
<RowDefinition Height="60"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="75" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Content="Text" Grid.Row="0" Grid.Column="0" />
<Label Content="Text" Grid.Row="1" Grid.Column="0" />
<Label Content="Text" Grid.Row="0" Grid.Column="1" />
<Label Content="Text" Grid.Row="1" Grid.Column="1" />
</Grid>
Now I want to print this Label. When I use the Function "PrintVisual" in a Loop the Printer stops after each Label for 1 - 2 seconds.
Therefore I tested this Code example but it doesen't work.
FixedDocument doc = new FixedDocument();
PageContent pc = new PageContent();
doc.Pages.Add(pc);
FixedPage page = new FixedPage();
pc.Child = page;
for (int i = 1; i <= int.Parse(tbCount.Text); i++)
{
page.Children.Add((UIElement)Label);
}
printDialog.PrintDocument(doc.DocumentPaginator, "Labels");
The error is thrown when the Label will be added to the page.

How to center a popup in window store app

I have a user control with custom popup (UserHelperButton). I have manually set the Vertical and Horizontal Offset to show popup on the right position. Now I need to update it's position to center. I'm not able to center it on x axis and on vertical.
On the root windows I add add UserHelperButton on different locations
<Grid Margin="0,0,0,25">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<UserControls:UserLabel Text="Varnost v dvoje" Grid.Column="0" />
<UserControls:UserCheckBox x:Name="cbxDouble" Grid.Column="1" cbxClick="cbxDouble_cbxClick" />
<UserControls:UserHelperButton Grid.Column="2" HelperText="V primeru, da se zavarujeta dve osebi, obe zavarovani osebi pridobita nižjo premijo za sklenjena zavarovanja." />
<UserControls:UserLabel x:Name="lblRefNum" Text="Referenčna številka" Grid.Column="3" />
<UserControls:UserCheckBox x:Name="cbxRefNum" Grid.Column="4" cbxClick="cbxRefNum_cbxClick" />
<UserControls:UserTextBox x:Name="txbRefNum" Grid.Column="5" ValidationMessage="Vnesite referenčno številko!" />
<UserControls:UserLabel Text="Zaposlen na Pošta Slovenija" Grid.Column="6" />
<UserControls:UserCheckBox x:Name="cbxPS" Grid.Column="7" cbxClick="cbxPS_cbxClick" />
or
<Grid Margin="0,25,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="500" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<UserControls:UserLabel Grid.Column="0" x:Name="lblInsurance" Text="Priporočena varnost do 65. leta" LabelMode="Heading" ValidationMessage="Vsota zavarovanj je premajhna!" />
<UserControls:UserHelperButton x:Name="helper2" Grid.Column="2" />
</Grid>
userControl xaml:
<Grid x:Name="grid" Margin="0" MaxHeight="50" Canvas.ZIndex="4" VerticalAlignment="Center">
<Button x:Name="btnHelper" AutomationProperties.Name="" Style="{StaticResource HelpAppBarButtonStyle}" HorizontalAlignment="Left" VerticalAlignment="Center" Height="70" Click="btnHelper_Click" />
<Popup x:Name="popHelper" IsLightDismissEnabled="True" VerticalOffset="-150" HorizontalOffset="-50">
<Border BorderThickness="25" CornerRadius="25" BorderBrush="Gray" Background="Gray">
<Grid Background="Gray" Width="400" Height="300">
<Grid.RowDefinitions>
<RowDefinition Height="60" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<local:UserLabel Text="Pomoč" LabelMode="Heading" VerticalAlignment="Top" />
<Button x:Name="btnClose" AutomationProperties.Name="" Grid.Row="0" Style="{StaticResource NoAppBarButtonStyle}" HorizontalAlignment="Right" VerticalAlignment="Top" Padding="12,0,0,0" Height="100" Click="btnClose_Click" RenderTransformOrigin="0.5,0.5" >
<Button.RenderTransform>
<CompositeTransform TranslateY="-15"/>
</Button.RenderTransform>
</Button>
<WebView x:Name="webviewControl" Grid.Row="1" Margin="0,20,0,0" Height="200" Width="400" />
</Grid>
</Border>
</Popup>
On load event I fill popup with help text
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
string html = "<html><body style=\"font-family: 'Segoe UI'; background-color: gray; color: white; margin: 0;\">" + g_text + "</body></html>";
var fragment = HtmlFormatHelper.GetStaticFragment(HtmlFormatHelper.CreateHtmlFormat(html));
webviewControl.NavigateToString(fragment);
}
So how can I do that?
Thx
Poki
I do it like this:
private void popup_Loaded(object sender, RoutedEventArgs e)
{
popup.HorizontalOffset = (Window.Current.Bounds.Width - popupGrid.Width) / 2;
popup.VerticalOffset = (Window.Current.Bounds.Height - popupGrid.Height) / 2;
}

access element component silverlight

I'm developing a player based on Silverlight 5 on MVVM pattern. I'm trying to change status buttons in code behind.
File : PlayerPage.xaml
My player component xaml :
<Grid x:Name="LayoutRoot">
<player:Player x:Name="Player"
Playlist="{Binding Playlist}"
CurrentPlaylistItem="{Binding CurrentPlaylistItem, Mode=TwoWay}"
IsSeekingEnabled="{Binding CanSeek}"
AutoLoad="True"
AutoPlay="True"
MediaEnded="Player_MediaEnded"
MediaOpened="Player_MediaOpened"
Style="{StaticResource PlayerStyle}"
PlaylistVisibility="Disabled"
LogLevel="Warning"
AutoHideControls="True"
AutoHideDelay="0:0:5"
AllowDoubleClickToggle="True"
RetryDuration="00:01:00"
RetryInterval="00:00:10"
BufferingTime="00:00:15"
/>
</Grid>
File : PlayerPage.xaml
Style of component player :
<Grid x:Name="ControllerContainer" Height="40" Grid.Row="4" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<CompositeTransform />
</Grid.RenderTransform>
<Grid.Background>
<ImageBrush ImageSource="component/Images/grid_background_player.jpg"
AlignmentY="Top" />
</Grid.Background>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid x:Name="playercontrols" Grid.Column="0" HorizontalAlignment="Left" Width="90">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Button x:Name="TbPlayElement" Click="TbPlayElement_Click" HorizontalAlignment="Left" Cursor="Hand" >
<Grid>
<Image Source="component/Resources/play.png" Stretch="Uniform" Height="16" Width="16" />
</Grid>
</Button>
Now in my code behind PlayerPage.cs, when I press the stop button, I want to change the image of the play button.
private void TbStopElement_Click(object sender, System.Windows.RoutedEventArgs e)
{
}
How can I access the play button in code behind ?
Attach to the Loaded event to save a reference of the image:
xaml:
<Image Source="component/Resources/play.png" Stretch="Uniform" Height="16" Width="16"
Loaded="ImageLoaded" />
code-behind:
private Image imageReference;
private void ImageLoaded(object sender, EventArgs e)
{
imageReference = sender as Image;
}
Then when you want to change the image:
private void TbStopElement_Click(object sender, System.Windows.RoutedEventArgs e)
{
if(imageReference != null)
{
imageReference.Source = new BitmapImage(new Uri("/YourAppName;component/Resources/YourImage.png", UriKind.Relative));
}
}
Access in your TbStopElement like this:
var grid = TbPlayElement.Content as Grid;
var playImage = grid.Children[0] as Image;
BitmapImage bitmap = new BitmapImage();
bitmap.UriSource = new Uri("newImage.png", UriKind.Relative);
playImage.Source = bitmap;
I suggest you this code
TbPlayElement.Source = new BitmapImage(new Uri("/TbPlayElement.content;component/NameNewImage.png", UriKind.Relative));
Remark : Check properties in Visual Studio for the xaml file,ensure that Build Action is set to Page.
Or you can use ToggleButton
link : http://msdn.microsoft.com/en-us/library/cc296245%28v=vs.95%29.aspx

How to expand a control

I've got a UserControl which has a grid, whose specification is as follows:
<Grid Name="fieldsGrid" Margin="15,0,0,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
</Grid>
The second column is the one of interest. It displays a checkbox, whose text is contained in a TextBlock and appears as "Text..." if it is too long. This is accomplished through code-behind (I have my reasons) like so:
CheckBox currentCheckbox = new CheckBox();
TextBlock block = new TextBlock();
block.MaxWidth = 100;
block.Text = text;
block.TextWrapping = TextWrapping.NoWrap;
block.TextTrimming = TextTrimming.WordEllipsis;
currentCheckbox.Content = block;
currentCheckbox.ToolTip = metaText;
currentCheckbox.SetValue(Grid.RowProperty, rowNumber);
currentCheckbox.SetValue(Grid.ColumnProperty, 1);
currentCheckbox.Margin = new Thickness(0, 10, 10, 0);
currentCheckbox.VerticalAlignment = VerticalAlignment.Center;
fieldsGrid.Children.Add(currentCheckbox);
The problem is that I want to expand this checkbox as the UserControl is resized, thus showing more text as the size increases. How can this be accomplished?
Why don't you try this and thus remove code-behind?
<Grid Name="fieldsGrid"
Margin="15,0,0,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<CheckBox Grid.Column="1"
Margin="0 10 10 0">
<CheckBox.Content>
<!-- Make a binding for the Text of TextBlock below -->
<TextBlock MaxWidth="{Binding ActualWidth,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type CheckBox}}}"
Text="Some Text LOng FFFFFFF DDDDDDDDDDDD"
TextTrimming="WordEllipsis"
TextWrapping="NoWrap" />
</CheckBox.Content>
</CheckBox>
</Grid>
That should give you the behavior your looking for and does everything your code-behind does(You need to sort the binding for text to the TextBlock ofc)
On OP's particular request (Code-Behind to be avoided if it can be):
Can add with the code-behind you got (at the end)
currentCheckbox.SizeChanged += (sender, args) => block.MaxWidth = args.NewSize.Width; // Subtract the checkbox indicator width from args.NewSize.Width here for accurate TextBlock Width measurement
Video Link
This appeared to work for me. I used XAML just to define the CheckBox and the TextBlock containing it's label content, like this:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="603.433" Width="730.97">
<Grid Name="fieldsGrid"
Margin="15,0,0,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Column 1"></TextBlock>
<TextBlock Grid.Column="2" Text="Column 3, a bit bigger"></TextBlock>
<TextBlock Grid.Column="3" Text="0" x:Name="txtWidth"></TextBlock>
<TextBlock Grid.Column="4" Text="Column 5, really really really big"></TextBlock>
<CheckBox Grid.Column="1" x:Name="testChk"
Margin="0 10 10 0">
<CheckBox.Content>
<TextBlock x:Name="txtForCheckBox"></TextBlock>
</CheckBox.Content>
</CheckBox>
</Grid>
</Window>
And then code-behind looks like this:
public MainWindow()
{
InitializeComponent();
testChk.SizeChanged += testChk_SizeChanged;
txtForCheckBox.Text = "Some text, test, test, test.";
txtForCheckBox.TextTrimming = TextTrimming.WordEllipsis;
txtForCheckBox.TextWrapping = TextWrapping.NoWrap;
}
void testChk_SizeChanged(object sender, SizeChangedEventArgs e)
{
txtForCheckBox.MaxWidth = testChk.ActualWidth;
txtWidth.Text = testChk.ActualWidth.ToString();
}
Hope that helps...

WPF: Canvas and zIndex? How does it work?

I have the following layou:
<s:SurfaceWindow x:Class="Prototype_Concept_2.SurfaceWindow1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="http://schemas.microsoft.com/surface/2008"
Title="Prototype_Concept_2"
>
<s:SurfaceWindow.Resources>
<ImageBrush x:Key="WindowBackground" Stretch="None" Opacity="0.6" ImageSource="pack://application:,,,/Resources/WindowBackground.jpg"/>
</s:SurfaceWindow.Resources>
<Grid Background="{StaticResource WindowBackground}" >
<Grid Name="ProjectsGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBox Name="ProjectsHeader" Grid.ColumnSpan="2" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" FontSize="25" Text="Please choose one of the following projects" Grid.Row="0"></TextBox>
<s:SurfaceButton Name="BottomButton" HorizontalAlignment="Right" FontSize="20" Width="100" Grid.Column="1" Grid.Row="2" Foreground="White" Content="Refresh"></s:SurfaceButton>
<s:SurfaceListBox Background="Black" Grid.ColumnSpan="2" Name="ProjectsList" Grid.Row="1" ItemsSource="{Binding Projects}"></s:SurfaceListBox>
<Label Name="ProjectsFooter" Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2" FontSize="15" Content="Fetching projects data ..."></Label>
</Grid>
<Grid ShowGridLines="True" Name="SmellHeader" Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="256"></ColumnDefinition>
<ColumnDefinition Width="256"></ColumnDefinition>
<ColumnDefinition Width="256"></ColumnDefinition>
<ColumnDefinition Width="256"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="38"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Rectangle Grid.Column="0" Grid.Row="0" Fill="Black"></Rectangle>
<Viewbox Grid.Column="0" Grid.Row="0" s:Contacts.PreviewContactDown="BrainClass_PreviewContactDown">
<Label Background="Black" Foreground="White" Content="BrainClass" HorizontalContentAlignment="Center"></Label>
</Viewbox>
<Rectangle Grid.Column="1" Grid.Row="0" Fill="Black"></Rectangle>
<Viewbox Grid.Column="1" Grid.Row="0">
<Label Background="Black" Foreground="White" Content="God Class" HorizontalContentAlignment="Center"></Label>
</Viewbox>
<Rectangle Grid.Column="2" Grid.Row="0" Fill="Black"></Rectangle>
<Viewbox Grid.Column="2" Grid.Row="0">
<Label Background="Black" Foreground="White" Content="Tradition Breaker" HorizontalContentAlignment="Center"></Label>
</Viewbox>
<Rectangle Grid.Column="3" Grid.Row="0" Fill="Black"></Rectangle>
<Viewbox Grid.Column="3" Grid.Row="0">
<Label Background="Black" Foreground="White" Content="RefusedParent Bequest" HorizontalContentAlignment="Center"></Label>
</Viewbox>
</Grid>
<Canvas Name="RootLayer" Grid.Row="1" Grid.ColumnSpan="4">
</Canvas>
</Grid>
</s:SurfaceWindow>
To the RootLayer I add some Ellipse. Later I want to reoder them:
internal void setFocus(SourceManager manager)
{
Console.WriteLine("Set focus to class " + getFullName());
foreach (SourceFile sf in manager.getBrainClasses())
{
sf.getVisualizer().Fill = Brushes.Red;
Canvas.SetZIndex(sf.getVisualizer(), 0);
}
this.getVisualizer().Fill = Brushes.Blue;
Canvas.SetZIndex(this.getVisualizer(), 1);
manager.window.RootLayer.InvalidateArrange();
manager.window.RootLayer.InvalidateVisual();
}
The Ellipse is referenced by this.getVisualizer();
However, nothing changes? How can I bring one Ellipse to the front?
It's not fully clear from your code post how the ellipses are added to the canvas but here is a small sample that does essentially what you want to do:
<Grid>
<Canvas x:Name="RootLayer" Width="500" Height="500" />
</Grid>
And in the constructor of the code behind, create some ellipses:
for (int i = 0; i < 10; i++)
{
Ellipse e = new Ellipse
{
Width = 100,
Height = 100,
Fill = new SolidColorBrush(
Color.FromArgb(0xDD,
(Byte) r.Next(255)
(Byte) r.Next(255)
(Byte) r.Next(255))),
Stroke = Brushes.Black,
StrokeThickness = 1,
};
e.MouseUp += new MouseButtonEventHandler(e_MouseUp);
Canvas.SetLeft(e, r.Next(400));
Canvas.SetTop(e, r.Next(400));
RootLayer.Children.Add(e);
}
Event handler to handle mouse click on the ellipses
void e_MouseUp(object sender, MouseButtonEventArgs e)
{
foreach (UIElement item in RootLayer.Children)
Panel.SetZIndex(item, 0);
Panel.SetZIndex((UIElement)sender, 1);
}
With the code above, whenever an ellipse is clicked (mouse up), it will raise above all the other ellipses in that canvas.

Categories

Resources