I have two user controls, WorkflowTileItemsControl and WorkflowTileControl. The WorkflowTileItemsControl hosts the WorkflowTileControl in an ItemsControl. However, there are dependency properties on the WorkflowTileControl that I would like to expose to anything using the WorkflowTileItemsControl. In order to do that here is ItemsControl code for WorkflowTileItemsControl.
<ItemsControl ItemsSource="{Binding Source={StaticResource WorkflowTilesViewSource}}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding WorkflowTileControl, ElementName=ctrlWorkflowTileItems}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
However this doesn't seem to work. It is only showing the last item in the ItemsControl. Below is code that works, and is the functionality I'm looking for (minus hard coding all the dependency properties).
<ItemsControl ItemsSource="{Binding Source={StaticResource WorkflowTilesViewSource}}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<OrderCommon:WorkflowTileControl IsReadOnly="True" Margin="5" TasksTitle="Defects" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
And this is what my calling code looks like.
<OrderCommon:WorkflowTileItemsControl WorkflowRequirementTypeCode="DISBURSEMENTDFCT" Margin="5" MinWidth="1000" MaxWidth="1250" HorizontalAlignment="Left">
<OrderCommon:WorkflowTileItemsControl.WorkflowTileControl>
<OrderCommon:WorkflowTileControl IsReadOnly="True" Margin="5" TasksTitle="Defects" />
</OrderCommon:WorkflowTileItemsControl.WorkflowTileControl>
</OrderCommon:WorkflowTileItemsControl>
I feel like there is some simple step I'm missing. I'm not sure if ContentPresenter is the right tool for the job. I haven't done anything like this in WPF before. Can someone please assist?
So after some days of research I've found a solution. The WorkflowTileItemsControl needs to expose a Dependency Property of a DataTemplate which will be bound to the ItemsTemplate for the ItemsControl. Here is the xaml for the WorkflowTileItemsControl:
<ItemsControl ItemsSource="{Binding Source={StaticResource WorkflowTilesViewSource}}" ItemTemplate="{Binding WorkflowTileTemplate, ElementName=ctrlWorkflowTileItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
And Here is the xaml for the calling control:
<OrderCommon:WorkflowTileItemsControl WorkflowRequirementTypeCode="DISBURSEMENTDFCT" Margin="5" Width="1130" HorizontalAlignment="Left">
<OrderCommon:WorkflowTileItemsControl.WorkflowTileTemplate>
<DataTemplate>
<OrderCommon:WorkflowTileControl IsReadOnly="True" Margin="5" TasksTitle="Defects" />
</DataTemplate>
</OrderCommon:WorkflowTileItemsControl.WorkflowTileTemplate>
</OrderCommon:WorkflowTileItemsControl>
Related
I have an ItemTemplateSelector that uses the typical C# code for logic, but that code never even gets called from my ItemsControl. Right now I have just stubbed in ONE of the Selector Display Templates for "StringTemplate" and I have those in my "Parameters" array, yet it never calls selector.
<Grid>
<ItemsControl ItemsSource="{Binding Parameters}">
<ItemsControl.Resources>
<local:ReportRun_LaunchView_ParameterTemplateSelector x:Key="TemplateSelector_FormDetails">
<local:ReportRun_LaunchView_ParameterTemplateSelector.StringTemplate>
<DataTemplate>
<fv:WatermarkTextBox
Grid.Row="1"
Grid.Column="0"
Margin="0,0,7,0"
fv:WpfMvmFocusManager.FocusKey="txtSearchNpi"
Text="{fv:OnChangedBinding Path=StringValue}"
WatermarkContent="{Binding DataContext.Name}" />
</DataTemplate>
</local:ReportRun_LaunchView_ParameterTemplateSelector.StringTemplate>
</local:ReportRun_LaunchView_ParameterTemplateSelector>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel
HorizontalAlignment="Stretch"
IsItemsHost="True"
Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl x:Name="items" ItemTemplateSelector="{StaticResource TemplateSelector_FormDetails}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
I am implementing User Controls in my application with MVVM structure. How can I bind different User Controls in a single page and show in a window screen.
Like below image. I want same as it is in the image.
ViewModel code
public RelayCommand OpenWidgetList => new RelayCommand(() =>
{
ControlList = new List<UserControl>();
ControlList.Add(ObjColumn1L);
ControlList.Add(ObjColumn1L);
ControlList.Add(ObjColumn1M);
ControlList.Add(ObjColumn1S);
ControlList.Add(ObjColumn1XL);
ControlList.Add(ObjColumn1XXL);
ControlList.Add(ObjColumn2L);
ControlList.Add(ObjColumn2M);
ControlList.Add(ObjColumn2S);
ControlList.Add(ObjColumn2XL);
ControlList.Add(ObjColumn2XXL);
ControlList.Add(ObjColumn3L);
ControlList.Add(ObjColumn3M);
ControlList.Add(ObjColumn3S);
ControlList.Add(ObjColumn4M);
ControlList.Add(ObjColumn4S);
}, true);
XAML Code
<UniformGrid Name="widgetData" Background="Black" VerticalAlignment="Top" Height="691" Margin="0,50,0,0">
<UniformGrid Columns="3">
<UniformGrid Rows="6">
<UniformGrid>
<ItemsControl ItemsSource="{Binding ControlList}" Name="UserControlColumn" Margin="4,0" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel HorizontalAlignment="Left" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<controls:UserControlColumn HorizontalAlignment="Left" Margin="2" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</UniformGrid>
</UniformGrid>
</UniformGrid>
</UniformGrid>
</Grid>
Yes, I found answer.
By coding I tried much but can not do that but in a simple way I had done by XAML side. Nothing but copy the code and separately bind each user Control with only one data from the back-end in DataCollection variable. Without binding each User Control from the back-end codes.
Below are my XAML code of WPF file. where repetedly done for each User Control to bind in the form.
<UniformGrid Rows="1">
<ItemsControl ItemsSource="{Binding DataCollection}" Name="UserControlColumn1" Margin="4,0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel HorizontalAlignment="Left" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<controls:UserControlColumn1 HorizontalAlignment="Left" Margin="2" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</UniformGrid>
<UniformGrid Rows="1">
<ItemsControl ItemsSource="{Binding DataCollection}" Name="UserControlColumn2" Margin="4,0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel HorizontalAlignment="Left" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<controls:UserControlColumn2 HorizontalAlignment="Left" Margin="2" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</UniformGrid>
<!--Same for other user Controls as above two...-->
Every user control has its own datacontext so in your main viewmodel you add a property for every usercontrol viewmodel and then you bind it. Something like this:
UserControl1ViewModel
{
....
}
MainViewModel
{
UserControl1ViewModel UserControl1ViewModel {get; private set;}
}
I have a question regarding nested collections usage in UWP apps with XAML/C#.
Let's say I have a list of items with multiple images in each.
I need to show a scrollable list with all of the images inside the item data.
So far I can see a solution to create GridView with ItemsTemplate that has ItemsControl inside it. But it seams very slow and not optimized solution.
Is there any better suggestion to solve that?
Without much context, I can only think of following :
You have a large amount of data to be displayed, but not all at once. In this case you should consider using controls that support virtualization.
Flattening the data source before binding it. This may improve the performance by a little.
Update
Here is how you can do it :
<ListViewItem ItemsSource="{Binding Posts}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Title}" />
<TextBlock Text="{Binding Message}" />
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Photos}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListViewItem>
I am working on c# xaml using silverlight and i am bit confused about the hierarchy of this xaml code:
<UserControl.Resources>
<this:MyValueConverter x:Key="TabConverter"/>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="Green">
<ItemsControl ItemsSource="{Binding Path=TabList, Mode=OneWay}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas></Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Width="150" Background="red" Height="100" Canvas.Left="{Binding TabList, Mode=TwoWay, Converter={StaticResource TabConverter}}" Canvas.Top="100" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
When i run it gives a big green color window(sorry if technical names are not correct), whereas it should also show red color somewhere in same window as it has Border Width="150" Background="red" .Could some one please explain me what this code is doing ?
ItemsControl really just binds to a list and applies a datatemplate (border with background red) for each item in the list. As for the reason you're only seeing green, well there's probably nothing in the TabList property on your viewmodel. That way, nothing in the items template renders, and all you see is green.
You'll need to make sure that TabList is bound correctly (it exists on your datacontext, whether that's a view model or not) and that it has items in it.
Here's a simpler version of what you may want to accomplish:
<Grid x:Name="LayoutRoot" Background="Green">
<ItemsControl ItemsSource="{Binding Path=TabList, Mode=OneWay}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Width="150" Background="red" Height="100" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
I am trying to do an interface in WPF where a list of item is displayed, taking as little vertical space as possible:
My instinct was to use an ItemsControl to bind my list, and to put the UI for each item into a WrapPanel. Unfortunately by default, each item starts at a new line regardless of the window's size. Adding a StackPanel with Orientation="Horizontal" makes all items in a single line, regardless of the size...
<!--<ScrollViewer Grid.Row="0" Grid.Column="0"
VerticalScrollBarVisibility="Auto">-->
<ItemsControl Margin="0,4" ItemsSource="{Binding Path=Watchers}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type Core:Watcher}">
<WrapPanel Orientation="Horizontal">
<TextBlock Margin="0,2" Text="{Binding Path=Name}"
Width="250px" />
<TextBox Text="{Binding Path=Value, Mode=OneWay}"
Width="300px">
</TextBox>
</WrapPanel>
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
<!--</ScrollViewer>-->
Any pointers?
Bonus point: Where should I add a ScrollViewer in order to have the behavior shown in my mockup?
Thanks a lot!
The WrapPanel has, as well as the StackPanel, an Orientation property, which defaults to Vertical. So your list should wrap (assuming you have enough space at hand) if your ItemsPanelTemplate looks like this:
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
About the ScrollViewer:
The desired behavior should be achieved by defining it like follows (not tested though, and I omitted all for this example unnecessary stuff):
<ScrollViewer HorizontalAlignment="Stretch">
<ItemsControl MinWidth="550" Width="{Binding ActualWidth, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ScrollViewer}}}" />
</ScrollViewer>
I think you want the WrapPanel in the ItemsPanel and the StackPanel in the ItemTemplate.
why not use the WrapPanel as ItemsPanelTemplate?
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
as long as the items have space to the left they would be arranged horizontal.