WPF Nested Databinding - wpf

I'm trying to bind data into nested StackPanels in WPF using the following code - to no avail. Can anybody spot where I'm going wrong?
<Page.Resources>
<DataTemplate x:Key="MinuteTimeSlotTemplate">
<TextBlock Text="{Binding Path=TourName}" Background="Blue" />
</DataTemplate>
<DataTemplate x:Key="HourlyTimeSlotTemplate">
<StackPanel>
<Border Height="120" BorderThickness="0,0,0,1" BorderBrush="#DDD" x:Name="parentRow">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="123"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Vertical" VerticalAlignment="Center" Margin="0,0,10,0" MouseUp="StackPanel_MouseUp_1">
<TextBlock Foreground="#4585B9" FontWeight="Bold" FontFamily="Trebuchet MS" FontSize="20" HorizontalAlignment="Right">
<Run Text="{Binding Path=Time}"/></TextBlock>
<TextBlock FontFamily="Trebuchet MS" Foreground="#808080" HorizontalAlignment="Right"><Run Text="View Bookings"/></TextBlock>
</StackPanel>
<StackPanel Orientation="Vertical" Grid.Column="1" Margin="10,0,10,0" x:Name="stk">
<ItemsControl ItemTemplate="{StaticResource MinuteTimeSlotTemplate}" ItemsSource="{Binding Path=HourlySlots}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
</Grid>
</Border>
</StackPanel>
</DataTemplate>
</Page.Resources>
<helpers:AnimatedScrollViewer x:Name="scrlHours" Grid.Column="1" PanningMode="Both" PanningDeceleration="5" PanningRatio="2">
<ItemsControl x:Name="TimeSlotList" ItemTemplate="{StaticResource HourlyTimeSlotTemplate}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</helpers:AnimatedScrollViewer>
I set the parent StackPanels ItemsSource in code:
public HourlyCalendar() {
InitializeComponent();
TimeSlotList.ItemsSource = new Models.TimeSlots(DateTime.Today).HourlySlots;
}
And here's my model:
public class TimeSlots {
public TimeSlots(DateTime? day) {
this.HourlySlots = DataManager.GetCalendarDayTimeSlots(day);
}
public IEnumerable<TimeSlot> HourlySlots { get; set; }
}
The parent StackPanel binds as expected, but I cannot figure out how to bind the child StackPanel...

Turns out it was rather simple:
<helpers:AnimatedScrollViewer x:Name="scrlHours" Grid.Column="1" PanningMode="Both" PanningDeceleration="5" PanningRatio="2">
<ItemsControl x:Name="TimeSlots">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Height="120" BorderThickness="0,0,0,1" BorderBrush="#DDD" x:Name="parentRow">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Vertical" VerticalAlignment="Center" Margin="0,0,10,0" Width="123" MouseUp="StackPanel_MouseUp_1"> <!--Height="{Binding Height, ElementName=parentRow}"-->
<TextBlock Foreground="#4585B9" FontWeight="Bold" FontFamily="Trebuchet MS" FontSize="20" HorizontalAlignment="Right">
<Run Text="{Binding Path=Time}"/></TextBlock>
<TextBlock FontFamily="Trebuchet MS" Foreground="#808080" HorizontalAlignment="Right"><Run Text="View Bookings"/></TextBlock>
</StackPanel>
<ListView ItemsSource="{Binding Bookings}" ScrollViewer.CanContentScroll="False">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding TourName}"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListView>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</helpers:AnimatedScrollViewer>

Related

Changing image width inside datatemplate dynamically with a slidercontrol

I have populated a Listview with Images and I want to change the size of the Images dynamically with a slider. I couldnt find any solution yet. How can I do that?
<ListView ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Width="{Binding ElementName=Windowdefault, Path=ActualWidth}" Margin="5" MouseDoubleClick="TvBox_MouseDoubleClick" x:Name="TvBox" VerticalAlignment="Top">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Wrapalign:AlignableWrapPanel HorizontalContentAlignment="Center" HorizontalAlignment="Center" ScrollViewer.HorizontalScrollBarVisibility="Disabled" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="stack" Margin="0 0 0 0" Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<StackPanel Margin="-25 -8 -25 -5">
<Image Width="100" x:Name="ImagesGrid" Source="{Binding ID,Converter={StaticResource ImagePathConverter}}" HorizontalAlignment="Stretch" VerticalAlignment="Top" Stretch="UniformToFill" />
<TextBlock x:Name="ID" HorizontalAlignment="Center" FontWeight="Light" Text="{Binding ID}" VerticalAlignment="Bottom" />
</StackPanel>
<TextBlock Visibility="Collapsed" x:Name="Flname" MaxWidth="60" TextAlignment="Center" FontSize="7" TextWrapping="Wrap" HorizontalAlignment="Center" FontWeight="Light" Text="{Binding Name}" VerticalAlignment="Bottom" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
This is pretty simple to accomplish.
Using your code as a starting point, I added a Slider with the x:Name="Slider". In the DataTemplate I setup a binding on the Image to be the Value of the Slider.
The Slider has a Minimum="100" and Maximum="1000" for the example.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Slider x:Name="Slider"
Grid.Row="0"
Interval="1"
Maximum="1000"
Minimum="100"
Value="100" />
<ListView
Grid.Row="1"
Margin="5"
VerticalAlignment="Top"
ItemsSource="{Binding Images}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel
Margin="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Orientation="Vertical">
<StackPanel>
<Image x:Name="ImagesGrid"
Width="{Binding ElementName=Slider, Path=Value}"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Source="{Binding Image}"
Stretch="UniformToFill" />
<TextBlock x:Name="ID"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
FontWeight="Light"
Text="{Binding Name}" />
</StackPanel>
<TextBlock
MaxWidth="60"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
FontSize="7"
FontWeight="Light"
Text="{Binding FileName}"
TextAlignment="Center"
TextWrapping="Wrap"
Visibility="Collapsed" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
I hope this helps!

WPF nested ItemsControl binding issue

Why is the second ItemsControl binding to FirstName not working?
<ItemsControl Grid.Row="1" x:Name="PMItmsControl" VerticalAlignment="Top" ItemsSource="{Binding FirstEntityCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border CornerRadius="5" BorderBrush="YellowGreen" BorderThickness="1" Margin="5">
<Grid Width="auto" Height="100" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60*"/>
<ColumnDefinition Width="40*"/>
</Grid.ColumnDefinitions>
<TextBlock **x:Name="tb"** Width="100" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10" Text="{Binding FirstName}" FontSize="10" >
</TextBlock>
<ItemsControl ItemsSource="{Binding SecondEntityCollection}" Grid.Column="1" VerticalAlignment="Top">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50*"/>
<ColumnDefinition Width="50*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding SecondName}" Margin="5" Foreground="White" />
<TextBlock Grid.Column="1" Text="{Binding **Path= Text, ElementName=tb**}" Margin="5" Width="40">
</TextBlock>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
and in my code behind, i declare following classes:
public class FirstEntity
{
public string FirstName { get; set; }
public ObservableCollection<SecondEntity> SecondEntityCollection { get; set; }
}
public class SecondEntity
{
public string SecondName { get; set; }
}
and the FirstEntityCollection is declare as following in my code behind:
public ObservableCollection<FirstEntity> FirstEntityCollection {get;set;}
not sure if i make my issue clear?
can someone give me any idea? please.
thanks much. very appreciate.
updated: I just found another solution use x:Name="tb" to above Bold code. and then changes Text="{Binding Path= DataContext.FirstName, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ItemsControl},AncestorLevel=2}}" to Text="{Binding Text,ElementName=tb}"
thanks Maxi.
----------------updated again-------------
this is the first time I asked question in stackoverflow, the question editor is not easy to input code and comments and the formatting is so bad, maybe I don't find a easy way to use. anyway thanks.
The first mess-up you need to get rid of is setting Foreground="White" on the TextBlock.
Based on your question update, please find below XAML bindings.
<ItemsControl Grid.Row="1" x:Name="PMItmsControl" VerticalAlignment="Top" ItemsSource="{Binding FirstEntityCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border CornerRadius="5" BorderBrush="YellowGreen" BorderThickness="1" Margin="5">
<Grid Width="auto" Height="100" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60*"/>
<ColumnDefinition Width="40*"/>
</Grid.ColumnDefinitions>
<TextBlock Width="100" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10" Text="{Binding FirstName}" FontSize="10" >
</TextBlock>
<ItemsControl ItemsSource="{Binding SecondEntityCollection}" Grid.Column="1" VerticalAlignment="Top">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50*"/>
<ColumnDefinition Width="50*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding SecondName}" Margin="5" />
<!--Notice setting DataContext to TextBlock below-->
<TextBlock Grid.Column="1" DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ItemsControl}}}" Text="{Binding Path= FirstName}" Margin="5" Width="Auto"/> </Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Hope this give you an idea to start with...

Nested ItemsControl Orientation

I have a nested ItemsControl. My data structure is an ObservableCollection of Campaigns which consist of a Campaign class and an observableCollection of Data counts (total, assigned, unassigned, closed). What I need is the following:
CAMPAIGN.NAME
TOTAL UNASSIGNED ASSIGNED CLOSED
CAMPAIGN.NAME
TOTAL UNASSIGNED ASSIGNED CLOSED
I am able to get the first part of this, but for some reason it will not honor the orientation for the second ItemsControl. What am I missing? My XAML is:
<ItemsControl x:Name="icCampaignChicklets" ItemsSource="{Binding CampChicks}" Grid.Row="1">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid x:Name="gridContent">
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock x:Name="CampaignHeader" Height="20" Text="{Binding Path=Campaign.Name}" Grid.Row="1" VerticalAlignment="Top" TextWrapping="Wrap" HorizontalAlignment="Left" />
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="10">
<ItemsControl x:Name="icChicklets" ItemsSource="{Binding Path=Data}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Width="150" Height="140" Background="{Binding Background}" Cursor="Hand"
MouseLeftButtonDown="Chicklet_MouseLeftButtonDown"
>
<Grid x:Name="gridContent" Margin="8,4">
<TextBlock Text="{Binding Caption}" Foreground="White" FontSize="17" />
<TextBlock Text="{Binding CountCaption, Mode=OneWay}" Foreground="White" FontSize="45" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="7" />
<TextBlock Text="Ú" Foreground="#99ffffff" FontSize="30" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="3,5" FontFamily="Wingdings 3" />
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
If you want to change the orientation of the contents of an ItemsControl, set its ItemsPanel property like so:
<ItemsControl
...attributes...
>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Wrapping it in a horizontally-oriented parent StackPanel will merely arrange it and its siblings horizontally, but in this particular case it has no siblings.

Why my stackpanel items always aligning to vertical if even i mentioned horizantalmode in silverlight?

I wrote the below code in my page:
<StackPanel HorizontalAlignment="Left" Height="166" Margin="10,602,0,0" VerticalAlignment="Top" Width="1346" x:Name="thumbnailViewer">
<ScrollViewer
x:Name="thumbnailViewerScroller"
Padding="0"
BorderThickness="0"
VerticalScrollBarVisibility="Hidden"
HorizontalScrollBarVisibility="Hidden">
<StackPanel Orientation="Horizontal" >
<ItemsControl x:Name="UserList">
<ItemsControl.ItemTemplate>
<DataTemplate>
<!--<StackPanel Orientation="Horizontal">-->
<Image Source="{Binding imageurl}" Tag="{Binding Path=id}" Width="164" Height="150" Margin="4" Stretch="Fill"></Image>
<!--</StackPanel>-->
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
</StackPanel>
Inside of the scrollviewer i mentionsed stackpanel and aligning the items as horizontal.But always i am getting the items alignment as vertical while running of the code.Please tell me how to align the items as horizontal?What was wrong in my code why items are aliging to vertical even i mentionsed Orientation="Horizontal in stackpanel.
EDIT:
<ScrollViewer
x:Name="thumbnailViewerScroller"
Padding="0"
BorderThickness="0"
VerticalScrollBarVisibility="Hidden"
HorizontalScrollBarVisibility="Hidden">
<!--<StackPanel Orientation="Horizontal" >-->
<ItemsControl x:Name="UserList">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<!--<DataTemplate>-->
<StackPanel Orientation="Horizontal">
<Image Source="{Binding imageurl}" Tag="{Binding Path=id}" Width="164" Height="150" Margin="4" Stretch="Fill"></Image>
</StackPanel>
<!--</DataTemplate>-->
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Scrollviewer>
</Stackpanel>
Use the ItemsPanel of the ItemsControl instead.
<ScrollViewer>
<ItemsControl ...>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding imageurl}"
Tag="{Binding Path=id}" Width="164" Height="150"
Margin="4" Stretch="Fill"></Image>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>

Horizontal stackpanel to wrap DataBinded ItemsControl

I have an ItemsControl for which the ItemsSource is Binded. i coded it as per the below so that it would add the UserControl (showing the different items) to a StackPanel with a horizontal orientation that then contains a wrappanel to wrap the items inside but it is not working. All of the items are showing but they are all on one line and do not wrap to a new line when needed.
How can this code be fixed to include wrapping?
<ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto"
Grid.Column="0" Grid.Row="1">
<ItemsControl x:Name="tStack"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto" Grid.Row="1"
ItemsSource="{Binding Items.View}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel x:Name="stckPnl" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<WrapPanel>
<Viewbox HorizontalAlignment="Left" Height="400">
<Controls1:MyItemsUserControl Padding="5"/>
</Viewbox>
</WrapPanel>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
I have solved this issue by setting Width for WrapPanel. In below snippet i have binded WrapPanel width to its Parent Grid control named MainGrid and Path to its ActualWidth. Please see below snippet will helps you sometimes to solve your issue
<ItemsControl Name="ThemesItemControl"
Grid.Column="1"
Grid.Row="1"
ItemsSource="{Binding InstalledCollection}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderThickness="0.5">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"
VerticalAlignment="Top"
Width="{Binding ElementName=MainGrid, Path=ActualWidth}"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<Button Width="210"
Height="260"
Margin="20"
Tag="{Binding ID}"
Command="{Binding DataContext.ThemeSelectCommand,RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}}}"
CommandParameter="{Binding RelativeSource={RelativeSource Self}}">
<StackPanel>
<Image Source="{Binding TileImage}"/>
</StackPanel>
</Button>
<TextBlock Text="{Binding Title}"
FontWeight="ExtraBold"
HorizontalAlignment="Center"
FontSize="15"
FontFamily="Segoe Print"
Foreground="Red"/>
<TextBlock Text="{Binding Description}"
HorizontalAlignment="Center"
FontSize="13"
FontFamily="Segoe Print"
Foreground="Red"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Resources