I am building an expander control where I want to have an additional button in the header (additional to the toggle). When I add a button on the <Expander.Header>, the binded command is not triggered when it is clicked.
I have tried creating a style/template for the Expander and Expander.Header so that the Expander's toggle is only triggered on its click (rather than the entire header). I did this thinking that it is some sort of heirarchical issue where the header is consuming the click event rather than my button, but it did not work out as I had hoped...
Is there a specific way I should modify the template to allow for a button to be placed in the header and have the button's command executed?
xaml of my expander control - all bound to my VM, can confirm the binding works correctly:
<Expander Background="White">
<Expander.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1"
VerticalAlignment="Center"
HorizontalAlignment="center"
FontSize="16"
Margin="5 0 5 0"
Text="{Binding Name}"/>
<Button
Grid.Column="2"
Width="15"
Height="15"
Margin="10 10 10 10"
Command="{Binding OpenButtonCommand}"/>
</Grid>
</Expander.Header>
<TextBlock Margin="30 0 0 0">This is a test sub component</TextBlock>
</Expander>
Thank you
Actually it should be working;
Tested with following VM:
using Prism.Commands;
using Prism.Mvvm;
using System;
namespace WpfApp2
{
public class MainViewModel : BindableBase
{
public DelegateCommand OpenButtonCommand { get; private set; }
private string m_Name = "Test Name";
public string Name
{
get { return m_Name; }
set
{
m_Name = value;
RaisePropertyChanged(nameof(Name));
}
}
public MainViewModel()
{
OpenButtonCommand = new DelegateCommand(OpenButtonCommandExecute);
}
private void OpenButtonCommandExecute()
{
Name = "clicked";
}
}
}
and XAML:
<Window.DataContext>
<local:MainViewModel />
</Window.DataContext>
<Grid>
<Expander
Width="300"
HorizontalAlignment="Left"
Background="White">
<Expander.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="1"
Margin="5,0,5,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="16"
Text="{Binding Name}"
TextAlignment="Left"
TextWrapping="Wrap" />
<Button
Grid.Column="2"
Width="15"
Height="15"
Margin="10,10,10,10"
Command="{Binding OpenButtonCommand}" />
</Grid>
</Expander.Header>
<TextBlock Margin="30,0,0,0">This is a test sub component</TextBlock>
</Expander>
</Grid>
Result:
Related
I am frustrated with the listview ItemSource and MVVM binding. I am binding the listview with a data model. After loading the listview, I add another item to the listview, the update is not reflected in listview, but it shows that the number of items in the list collection is increased by one. If I add the add in the list collection in the constructor, it is shown in the listview.
XAML
<Page
x:Class="App20.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App20"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page.DataContext>
<local:VictimsController></local:VictimsController>
</Page.DataContext>
<Grid Padding="10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<TextBlock Text="List of Victims/Trapped" HorizontalAlignment="Center" Style="{StaticResource HeaderTextBlockStyle}"/>
</Grid>
<Grid Grid.Row="1">
<ListView x:Name="ls" ItemsSource="{Binding VictimList, Mode=TwoWay}">
<ListView.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock FontWeight="Bold" HorizontalAlignment="Center" Grid.Column="0" Text="GPSLatitute" />
<TextBlock FontWeight="Bold" HorizontalAlignment="Center" Grid.Column="1" Text="GPSLongtitude" />
<TextBlock FontWeight="Bold" HorizontalAlignment="Center" Grid.Column="2" Text="Date" />
</Grid>
</DataTemplate>
</ListView.HeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock HorizontalAlignment="Center" Grid.Column="0" Text="{Binding GPSLatitute}" />
<TextBlock HorizontalAlignment="Center" Grid.Column="1" Text="{Binding GPSLongtitude}" />
<TextBlock HorizontalAlignment="Center" Grid.Column="2" Text="{Binding Date}" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Grid>
<Button Content="Publish" VerticalAlignment="Top"
Height="76" Width="114" Click="Publish_Click" />
</Grid>
Controller
public class VictimsController : INotifyPropertyChanged
{
List<VictimProfile> _victims = new List<VictimProfile>();
public VictimsController()
{
//Victims.Add(new VictimProfile() { GPSLatitute = 123, GPSLongtitude = 2333 });
}
public List<VictimProfile> VictimList
{
get
{
return _victims;
}
set
{
_victims = value;
OnPropertyChanged("VictimList");
}
}
public void addVictim(VictimProfile profile)
{
_victims.Add(profile);
OnPropertyChanged("VictimList");
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Adding one item to the listview model or collection
async void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
{
string ReceivedMessage = Encoding.UTF8.GetString(e.Message);
//convert the message to json format
var payLoad = JsonConvert.DeserializeObject<VictimProfile>(ReceivedMessage);
// we need this construction because the receiving code in the library and the UI with textbox run on different threads
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {
txt.Text += ReceivedMessage;
VictimsController model = this.DataContext as VictimsController;
model.addVictim(payLoad); //add item to the list collection
Debug.WriteLine("count: " + ls.Items.Count); //this shows that listview has one more item added to it, but nothing is shown in the listview
//ls.Items.Add(payLoad);
});
}
The point is the list collection has the new item and the ls (listview) also has the item, but it is not shown in the listview.
Finally I solved it.
Changing the list to observable collection has solved the problem.
ObservableCollection<VictimProfile> _victims = new ObservableCollection<VictimProfile>();
I have a UserControl that has a ViewModel containing an instance of my own custom class, call it Person. This ViewModel is set as the DataContext of the control. I am wanting to use this control in my main window which has, in its ViewModel a List of type Person called People. I am calling the control in my xaml like this:
<ItemsControl ItemsSource="{Binding People}">
<ItemsControl.ItemsTemplate>
<DataTemplate>
<userControls:PersonDetails />
</DataTemplate>
</ItemsControl.ItemsTemplate>
</ItemsControl>
Properties within the control are bound in this manner.
<TextBlock Text="{Binding Person.Name}" />
When I run I am getting the correct number of Controls for the amount of People in the list but no details are populated. I know I am doing something simple wrong but can't find it. Please help.
EDIT:
My UserControl xaml looks like this:
<UserControl x:Class="AddressBook.UserControls.PersonDetails"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:AddressBook.UserControls"
xmlns:vm="clr-namespace:AddressBook.ViewModels"
xmlns:enums="clr-namespace:AddressBook.Models"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="1000">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="40" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TextBlock Style="{StaticResource PersonDetailHeader}" Text="Person Name:" />
<TextBlock Style="{StaticResource PersonDetailValue}" Grid.Column="1" Text="{Binding Person.Name,
UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Style="{StaticResource PersonDetailHeader}" VerticalAlignment="Center" Grid.Row="1" Text="Street Address:" />
<TextBlock Style="{StaticResource PersonDetailValue}" Grid.Row="1" Grid.Column="1"
Text="{Binding Person.StreetAddress, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Style="{StaticResource PersonDetailHeader}" Grid.Row="2" Text="Town:" />
<TextBlock Style="{StaticResource PeronDetailValue}" Grid.Row="2" Grid.Column="1"
Text="{Binding Person.Town, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Style="{StaticResource PersonDetailHeader}" Grid.Row="3" Text="County:" />
<TextBlock Style="{StaticResource PersonDetailValue}" Grid.Row="3" Grid.Column="1"
Text="{Binding Person.County, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Style="{StaticResource PersonDetailHeader}" Grid.Row="4" Text="Postcode:" />
<TextBlock Style="{StaticResource PersonDetailValue}" Grid.Row="4" Grid.Column="1"
Text="{Binding Person.Postcode, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Style="{StaticResource PersonDetailHeader}" Grid.Row="5" Text="Phone:" />
<TextBlock Style="{StaticResource PersonDetailValue}" Grid.Row="5" Grid.Column="1"
Text="{Binding Person.Phone, UpdateSourceTrigger=PropertyChanged}" />
<StackPanel Grid.Row="7" Grid.ColumnSpan="2" HorizontalAlignment="Center" Orientation="Horizontal">
<Button Style="{StaticResource ButtonStyle}" Content="Click" Command="{Binding ButtonClickCommand}" />
</StackPanel>
</Grid>
UserControl ViewModel:
public class PersonDetailsViewModel
{
public Person Person { get; set; }
public Command ButtonClickCommand { get; }
public PersonDetailsViewModel()
{
ButtonClickCommand = new Command(ButtonClick);
}
private void ButtonClick(object obj)
{
throw new NotImplementedException();
}
UserControl.xaml.cs:
public partial class PersonDetails : UserControl
{
public PersonDetails()
{
InitializeComponent();
}
}
Person.cs
public class Person : BaseModel
{
public string Name
{
get { return name; }
set
{
name = value;
NotifyPropertyChanged();
}
etc....
MainViewModel:
public class MainViewModel : BaseViewModel
{
public ObservableCollection<Person> People { get; }
= new ObservableCollection<Person>();
public MainViewModel()
{
PopulatePeople();
}
}
Now I understand why you were creating the PersonDetailsViewModel in the UserControl XAML, and what the problem was with the command.
The simplest way to fix this is to make MainViewModel.People a collection of PersonDetailsViewModel instead of Person. That's what I'd do.
But if you want to leave MainViewModel.People as it is, while still using PersonDetailsViewModel inside your UserControl, that makes sense to me. You could do this:
.xaml
<UserControl
x:Class="AddressBook.UserControls.PersonDetails"
DataContextChanged="PersonDetails_DataContextChanged"
...etc...
>
<!-- Give the Grid a name... -->
<Grid x:Name="OuterGrid">
.xaml.cs
public PersonDetails()
{
InitializeComponent();
}
private void PersonDetails_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
// ...so we can give the Grid a different DataContext
OuterGrid.DataContext = new PersonDetailsViewModel {
Person = (Person)this.DataContext
};
}
Now it will inherit a Person for its DataContext, but internally it will use a PersonDetailsViewModel based on that Person.
Not sure if that's what you are trying to do.
If you only wish to display some carac of every Person present in your People List you could do :
<Grid>
<ItemsControl ItemsSource="{Binding People}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="0,0,0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" />
<TextBlock Grid.Column="1" Text="{Binding Age}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
That will bind you Text on the Name property of each element of your list, so on the name of each Person of your list.
As your ItemsSource is already bound to People, the Binding of your Items is already on each Person of your List, so you should call your properties directly as {Binding Name} and not {Binding Person.Name}
<Page.Resources>
<ResourceDictionary>
<BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter" x:Name="testTest" />
</ResourceDictionary>
</Page.Resources>
itemscontrol:
<Grid Grid.Row="1" Grid.ColumnSpan="2" Name="testName">
<ScrollViewer VerticalScrollBarVisibility="Hidden" PanningMode="Both">
<ItemsControl ItemsSource="{Binding Path=NextMeetingList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Grid.Column="0" Grid.Row="0">
<Border x:Name = "myVariable" Grid.Column="0" Grid.Row="0" Margin="10" Height="30" Background="#A2C2E7" CornerRadius="5" BorderBrush="#A2C2E7">
<Grid Margin="8,0,8,0" Background="#A2C2E7">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Foreground="White" FontWeight="Bold" FontSize="15" Margin="0,4,0,0" HorizontalAlignment="Left">month</TextBlock>
<TextBlock Grid.Row="0" Grid.Column="1" Foreground="White" FontWeight="Bold" FontSize="15" Margin="0,4,0,0" HorizontalAlignment="Right">1 Meeting</TextBlock>
</Grid>
</Border>
<Border Grid.Column="0" Grid.Row="0" Margin="10" Height="60" Background="GhostWhite" CornerRadius="3" BorderBrush="{Binding BorderColor}" BorderThickness="0,8,0,0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="118"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" FontSize="40" Margin="10,5,0,0" Style="{DynamicResource Lato-Semibold}" Text="{Binding endDate.Day}"/>
<TextBlock Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" FontSize="12" Margin="77,13,0,0" Height="Auto" Style="{DynamicResource Lato-Semibold}" Text="{Binding DayString}"/>
<TextBlock Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" FontSize="14" Margin="70,26,0,0" Height="Auto" Style="{DynamicResource Lato-Semibold}" Text="{Binding endDate.Hour}"/>
<TextBlock Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" FontSize="14" Margin="86,26,0,0" Height="Auto" Style="{DynamicResource Lato-Semibold}" Text=":"/>
<TextBlock Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" FontSize="14" Margin="90,26,0,0" Height="Auto" Style="{DynamicResource Lato-Semibold}" Text="{Binding MinuteString}"/>
<Border Grid.Row="0" Grid.Column="0" Width="1" BorderBrush="#BABABA" Height="40" Margin="115,-6,0,0" BorderThickness="1" HorizontalAlignment="Left"></Border>
<TextBlock Grid.Row="0" Grid.Column="1" HorizontalAlignment="Left" Text="{Binding subject}" FontWeight="Bold" FontSize="17" Margin="10,10,0,0"/>
<TextBlock Grid.Row="0" Grid.Column="1" Width="Auto" TextWrapping="Wrap" HorizontalAlignment="Left" Text="{Binding descr}" FontSize="10" Margin="20,27,150,0"/>
<TextBlock Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right" Text="{Binding companyName}" FontSize="10" Margin="0,10,30,0"/>
<TextBlock Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right" Text="sala del consiglio" FontSize="10" Margin="0,27,30,0"/>
<TextBlock Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right" Text=">" FontSize="15" VerticalAlignment="Center" Margin="0,-5,10,0"/>
</Grid>
</Border>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
Hello everyone , I should be able to make a grid Collapsed inside a ItemsControl in WPF .
The problem is that I can not understand how to use the booleanToVisibilityConverter from code behind .
Maybe I'm missing out on a glass of water but I can not connect how to do, if the name TestTest septum can not see it then the code-behind .
from code behind i don't see "myVariable"
To get hold of the converter from code-behind, you'd have to look it up in the Page's Resources dictionary. Do something like this in your Page class:
IValueConverter converter = this.Resources["booleanToVisibilityConverter"] as IValueConverter;
Giving the converter's resource entry a Name is not necessary; here you want to use the Key. Also, converters are normally used with XAML bindings -- if you want one in code, you can just instantiate one:
IValueConverter converter = new BooleanToVisibilityConverter();
Common usage goes something like this:
<Window.Resources>
<ResourceDictionary>
<BooleanToVisibilityConverter x:Key="Converter" />
</ResourceDictionary>
</Window.Resources>
<Grid Visibility="{Binding Display, Converter={StaticResource Converter}}">
...
</Grid>
Code-behind, using the window class itself as the data context:
public partial class MainWindow
{
public bool Display { get; set; };
public MainWindow()
{
InitializeComponent();
DataContext = this; // For the binding
Display = true;
}
}
Okay, one more, this time without data binding or converter:
<Grid x:Name="myGrid">
...
</Grid>
Code-behind:
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
myGrid.Visibility = Visibility.Visible;
}
}
The above doesn't explain why the OP couldn't reference "myVariable" from code-behind. That's because it's in a template, which is instantiated (dynamically) once per item in the collection.
It's still possible to get at it from code -- dynamically. For example, this XAML uses a DataTemplate:
<ItemsControl ItemsSource="{Binding Names}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid x:Name="innerGrid" Loaded="OnGridLoaded" DataContext="{Binding Name, Mode=OneWay}">
<TextBox Text="{Binding Path=., Mode=OneWay}" />
</Grid>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The following code-behind lets us reach into the template and make "innerGrid" disappear selectively:
public class Data
{
public string Name { get; }
public Data(string name)
{
Name = name;
}
}
public partial class MainWindow
{
public Data[] Names { get; } = { new Data("Hello"), new Data("World") };
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
private void OnGridLoaded(object sender, RoutedEventArgs e)
{
Grid outerGrid = sender as Grid;
Grid innerGrid = outerGrid?.FindName("innerGrid") as Grid;
if (innerGrid != null)
{
string name = innerGrid.DataContext as string;
if (name == "Hello")
{
innerGrid.Visibility = Visibility.Collapsed;
}
}
}
}
(To make the string easily accessible I bound the Data object to the "innerGrid" DataContext.)
I'm trying to find a way to display a horizontal List of items in WPF, the trick is that the Window which contains the List will be displayed on various screen sizes and all the items in the list need to be resized to fill the available space without any use of scroll bars.
I've found that a ViewBox control can be used to achieve the desired affect, but the ViewBox works only if I set <RowDefinition Height="300"/>.This approach doesn't work because if you have a certain number of items in the List they start becoming cut off.
If I remove <RowDefinition Height="300"/> then the first item in the list fills the screen and the rest are cut off
Any suggestions on how I can make all the items in the list resize to fill the available space no matter what the screen resolution is?
XAML:
<Window x:Class="ViewBoxExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" WindowState="Maximized">
<ItemsControl ItemsSource="{Binding Path=Employees}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="300"/>
</Grid.RowDefinitions>
<Viewbox Grid.Row="0" Grid.Column="0">
<TextBlock Text="{Binding Path=Name}" />
</Viewbox>
<Viewbox Grid.Row="0" Grid.Column="1">
<TextBlock Text="{Binding Path=Surname}" />
</Viewbox>
<Viewbox Grid.Row="0" Grid.Column="2">
<TextBlock Text="{Binding Path=Age}" />
</Viewbox>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>
C#:
using System.Collections.Generic;
using System.Windows;
namespace ViewBoxExample
{
public partial class MainWindow : Window
{
public List<Employee> _employees = new List<Employee>();
public List<Employee> Employees
{
get { return _employees; }
set { _employees = value; }
}
public MainWindow()
{
InitializeComponent();
Employees = new List<Employee>()
{
new Employee{ Name="Name1",Surname="Surname1",Age=20},
new Employee{ Name="Name2",Surname="Surname2",Age=30},
new Employee{ Name="Name3",Surname="Surname3",Age=40},
new Employee{ Name="Name4",Surname="Surname4",Age=50},
new Employee{ Name="Name5",Surname="Surname5",Age=60},
};
this.DataContext = this;
}
}
public class Employee
{
public string Name { get; set; }
public string Surname { get; set; }
public int Age { get; set; }
}
}
Just put your ItemsControl in ViewBox
<Viewbox>
<ItemsControl ItemsSource="{Binding Path=Employees}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Viewbox Grid.Row="0" Grid.Column="0">
<TextBlock Text="{Binding Path=Name}" />
</Viewbox>
<Viewbox Grid.Row="0" Grid.Column="1">
<TextBlock Text="{Binding Path=Surname}" />
</Viewbox>
<Viewbox Grid.Row="0" Grid.Column="2">
<TextBlock Text="{Binding Path=Age}" />
</Viewbox>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Viewbox>
EDIT: if i am doing the same type of thing i would use the actual Height and Width approach as explained by Kent Boogaart in this Answer
I have the following XAML:
<Grid x:Name="ContentPanelDaily"
Grid.Row="1"
<Grid.RowDefinitions>
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60" />
<ColumnDefinition Width="80" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0"
Grid.Column="0"
Style="{StaticResource PhoneTextAccentStyle}"
Margin="0,0,0,0">
First
</TextBlock>
<TextBlock Grid.Row="0"
Grid.Column="1"
Style="{StaticResource PhoneTextAccentStyle}"
Margin="0,0,0,0">
Second
</TextBlock>
</Grid>
How can i detect which row was clicked in Tap event? I have tried to find SelectedRow or something like this but it seems there is no anything like this in Grid. Thank you very much.
Put your data into a button, and subscribe to on OnClick event.
<Button OnClick="evetnHandler">
<TextBlock Grid.Row="0"
Grid.Column="0"
Style="{StaticResource PhoneTextAccentStyle}"
Margin="0,0,0,0">
First
</TextBlock>
</Button>
Also, as #Rachel said: you can use a ListBox.
<ListBox ItemsSource="{Binding Items}"
SelectedItem="{Binding Selected, Type=TwoWay}">
<ListBox.ItemTemplate>
<DataTemlate>
<TextBlock
Style="{StaticResource PhoneTextAccentStyle}"
Margin="0,0,0,0" Text="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And in a code-behind create
public ObservableCollection<DataItem> Items {get;set;}
private DataItem _selected;
public DataItem Selected
{
get {return _selected;}
set
{
_selected = value;
//ha! item selected!!! handle it
}
}
public class DataItem
{
public string Name {get;set;}
}