i have this code
<Grid Width="160" x:Name="grd">
<Grid.Background>
<ImageBrush x:Name="img" ImageSource="Assets/Icons/tab-inactive.png" />
</Grid.Background>
<TextBlock x:Name="txtacticve" Text="Rating" Tap="TextBlock_Tap_1" />
</Grid>
while tapping the textblock the tap event will be called.how can i get the complete path of the imagesource in this tap event in code behind? i am really at the lost here how to get to the imagesource in my codebehind event.
One solution could be the following one :
In your XAML code, you can bind your TextBlock.Tag property to the Grid.Background property you need. It could be useful to do it in XAML rather than code behind if your Grid is not the first parent (no need to find the required parent with recursive C# code) :
<Grid Width="160" x:Name="grd">
<Grid.Background>
<ImageBrush x:Name="img" ImageSource="Assets/Icons/tab-inactive.png" />
</Grid.Background>
<TextBlock x:Name="txtacticve" Text="Rating" Tap="TextBlock_Tap_1" Tag="{Binding ElementName=grd, Path=Background}" />
</Grid>
Then in your code behind, you just have to cast and use the TextBlock.Tag property that way :
private void TextBlock_Tap_1(object sender, System.Windows.Input.GestureEventArgs e)
{
var textBlock = sender as TextBlock;
if (textBlock != null)
{
var test = ((BitmapImage)((ImageBrush)textBlock.Tag).ImageSource).UriSource.OriginalString;
}
}
Try this.
private void TextBlock_Tap_1(object sender, System.Windows.Input.GestureEventArgs e)
{
var grid = (Grid)txtacticve.Parent;
var img = grid.Background;
var path = ((BitmapImage)(((ImageBrush)(img)).ImageSource)).UriSource.AbsolutePath;
}
Related
<GridView x:Name="MainGridStations" ItemsSource="{x:Bind Stations}" IsItemClickEnabled="True" ItemClick="GridView_ItemClick">
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:Station">
<Grid x:Name="WantToSelectByCode">
<Grid Background="White" HorizontalAlignment="Center" Width="300" Height="200" VerticalAlignment="Center">
<Grid Background="#e4f0fc" Height="65" VerticalAlignment="Bottom" Opacity="0.8">
<TextBlock x:Name="StationName" Text="{Binding Name}" FontWeight="Bold" Foreground="#2c9a8b" HorizontalAlignment="Center" />
</Grid>
</Grid>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
I'm trying to select a child by index of a dynamically filled gridview but what i've tried always returns null.
Like so for the first child for example:
var container = MainGridStations.ContainerFromIndex(0);
var presenter = VisualTreeHelper.GetChild(container, 0) as GridViewItem;
What am I doing wrong here?
You can get the corresponding GridViewItem from the method ItemsControl.ContainerFromIndex(Int32) directly and don't need to use the VisualTreeHelper to get it again.
var container = MainGridStations.ContainerFromIndex(0);
GridViewItem gridViewItem= container as GridViewItem;
gridViewItem.Background = new SolidColorBrush(Colors.Red);
The container have been the corresponding GridViewItem got from the index.
Note that: since your inner Grid have a Background="White" property configuration, you can delete the code to see the effect more obviously using my above code to change the gridViewItem.Background.
---Update---
You must get the GridViewItem after the items loaded. You can try the code in your GridView_ItemClick event handler or the page's loaded event hander. Also pay attention to my above note that to get more obvious effect, please delete the Background="White" in your above xaml code.
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var container = MainGridStations.ContainerFromIndex(0);
GridViewItem gridViewItem = container as GridViewItem;
gridViewItem.Background = new SolidColorBrush(Colors.Green);
}
//get the item here
private void GridView_ItemClick(object sender, ItemClickEventArgs e)
{
var container = MainGridStations.ContainerFromIndex(0);
GridViewItem gridViewItem= container as GridViewItem;
gridViewItem.Background = new SolidColorBrush(Colors.Red);
//var presenter = VisualTreeHelper.GetChild(container, 0) as GridViewItem;
}
I have following working XAML and C# code behind:
<Grid x:Name="MainGrid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<GridView ItemsSource="{Binding}">
<GridView.ItemTemplate>
<DataTemplate>
<Grid Height="100" Width="150">
<Grid.Background>
<SolidColorBrush Color="{Binding Color}"/>
</Grid.Background>
<StackPanel>
<StackPanel.Background>
<SolidColorBrush Color="{Binding Color}"/>
</StackPanel.Background>
<TextBlock FontSize="15" Margin="10" Text="{Binding Name}"/>
</StackPanel>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
CODE behind:
public MainPage()
{
this.InitializeComponent();
var _Colors = typeof(Colors)
.GetRuntimeProperties()
.Select(x => new
{
Color = (Color)x.GetValue(null),
Name = x.Name
});
this.DataContext = _Colors;
}
This works fine.
But I want to do all the XAML part in C# code behind. In XAML, only MainGrid will be there, all its child elements and bindings needs to be done in code behind.
I have tried something like this in MainPage_Loaded event:
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
try
{
GridView gridView = new GridView()
{
ItemTemplate = new DataTemplate
{
//Don't know what to add here
}
};
Grid grid = new Grid();
Binding bindingObject = new Binding();
bindingObject.Source = this;
grid.SetBinding(Grid.BackgroundProperty, bindingObject);
//...
// Don't know how to add grid inside gridView in Code.
//...
MainGrid.Children.Add(gridView);
}
catch (Exception ex)
{
}
}
First of all I'd like to advise you not to create elements in code unless you have a real good reason to do so.
Regardless, considering that item templates are factory-like objects for controls (you 'spawn' a new set of controls for each item). You use the FrameworkElementFactory to model the subtree and then assign that the item template's VisualTree property.
I have xaml button like so:
<Button Click="SyncToDeviceToggle_OnClick">
<Button.Template>
<ControlTemplate>
<Image Source="Img/kin.png" Height="25"/>
</ControlTemplate>
</Button.Template>
</Button>
Code behind:
private void SyncToDeviceToggle_OnClick(object sender, RoutedEventArgs e)
{
var image = ??//I want to get the child image element in the button without having to search for it by name specified in name="something"
}
In javascript i would just do
button.getElementsByTagName("image")[0];
You could assign a name to the Image control and then access it by means of the FindName method of the Button's Template:
<ControlTemplate>
<Image x:Name="image" Source="Img/kin.png" Height="25"/>
</ControlTemplate>
...
private void Button_Click(object sender, RoutedEventArgs e)
{
var control = (Control)sender;
var image = control.Template.FindName("image", control) as Image;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
DependencyObject child = VisualTreeHelper.GetChild(button, 0);
Image image = child as Image;
//Now you can access your image Properties
}
<Button Click="SyncToDeviceToggle_OnClick" Margin="0,224,0,302">
<Button.Background>
<ImageBrush ImageSource="Img/kin.png" x:Name="MyBrush"/>
</Button.Background>
</Button>
If done in this way, you can directly access MyBrush by its direct name in the .cs file.
I got a canvas with some children.
<Canvas Name="Canvas" MouseDown="getElements">
<Rectangle Height="200" Width="200" Name="Element1"/>
<Rectangle Height="200" Width="200" Name="Element2"/>
</Canvas>
and by clicking on a canvas element I want to get the name of the clicked element with something like this:
public void getElements(object Sender, EventArgs e)
{
DependencyObject dpobj = Sender as DependencyObject;
string name = dpobj.GetValue(FrameworkContentElement.NameProperty) as string;
Console.WriteLine("Element Clicked: " + name);
}
but I only get the name of the canvas. can anybody help me to get the names of the clicked elements?
thanks in advance!
Since MouseDown is routed event instead of EventArgs use RoutedEventArgs or for MouseDown you can use MouseButtonEventArgs. It will give you OriginalSource property and you can try getting Name of e.OriginalSource:
private void getElements(object sender, MouseButtonEventArgs e)
{
var elementName = (e.OriginalSource as FrameworkElement).Name;
}
The event is routed from the elements in the canvas. To get the original source you can use the RoutedEventArgs instead:
public void getElements(object Sender, RoutedEventArgs e)
{
DependencyObject dpobj = e.OriginalSource as DependencyObject;
string name = dpobj.GetValue(FrameworkContentElement.NameProperty) as string;
Console.WriteLine("Element Clicked: " + name);
}
You can create an Event Handler for the MouseLeftButtonUp event on your Canvas (as WPF uses Routed Events, the event will 'bubble' up to parents and will be raised there, too). The XAML code would look somewhat like this:
<Window x:Class="CanvasChildren.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Canvas MouseLeftButtonUp="UIElement_OnMouseLeftButtonUp">
<Rectangle Canvas.Top="10" Canvas.Left="10" Height="200" Width="200" Name="Element1" Fill="LightBlue"/>
<Rectangle Canvas.Left="250" Canvas.Top="100" Height="200" Width="200" Name="Element2" Fill="DarkSalmon"/>
</Canvas>
</Window>
In your code behind file, you can retrieve the original object that was clicked by accessing the Source property of the event arguments, like shown in this code:
private void UIElement_OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var rectangle = (Rectangle) e.Source;
var name = rectangle.Name;
}
You can download my full example here (it's a Dropbox link).
I defined the following DataTemplate for a LibraryContainer:
<DataTemplate x:Key="ContainerItemTemplate">
<Grid>
<Border BorderThickness="1" BorderBrush="White" Margin="3">
<s:SurfaceTextBox IsReadOnly="True" Width="120" Text="{Binding Path=name}" Padding="3"/>
</Border>
<s:SurfaceButton Content="Expand" Click="SourceFilePressed"></s:SurfaceButton>
</Grid>
</DataTemplate>
The SourceFilePressed is the following:
private void SourceFilePressed(object sender, RoutedEventArgs e)
{
Logging.Logger.getInstance().log(sender.ToString());
e.Handled = true;
}
In the method SourceFilePressed who can I get the object that is binded to the SurfaceTextBox that is in the same grid as the pressed button? Can I somehow in the DataTemplate attach this object to the Click-Event?
If I parsed your question correctly, I think you could do this:
private void SourceFilePressed(object sender, RoutedEventArgs e)
{
var obj = (sender as FrameworkElement).DataContext;
}
To explain: the sender is the source of the event, so it's the SurfaceButton. It is a FrameworkElement and thus has a DataContext property. The DataContext is an inherited property, so unless you set it explicitly on the SurfaceButton, it will inherit it's DataContext from its parent (the Grid). The DataTemplate's DataContext is the data item it is templating, so you can see that the SurfaceButton will have that same object as its DataContext.