WPF/XAML Intuitive UserControl - wpf

what steps must be done to make a user control, to work in such order:
<local:MyUserControl ItemsSource="{Binding Items}">
<local:MyUserControl.Items>
<local:MyUserControl.Item Name="{Binding Name}"/>
</local:MyUserControl.Items>
</local:MyUserControl>
I know that for ItemsSource I need to create DependencyProperty, but what for the part which is inside MyUserControl.
Example:
Look below is an example how I used to do it.
This is called MyUserControl
<UserControl>
<Grid>
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Name}" Margin="3,3,3,3"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</UserControl>
MainPage:
<local:MyUserControl />
As you can see in this scenario, MyUserControl is not universal, it can be used properly ONLY if I have ItemsSource called Items, and inside of it there is a property called Name.
My Intention is to create flexible MyUserControl.
Thanks in advance.

Related

Change element inside Template

I want to reuse the the ItemsControl from my ListView and its not really hard to put the ItemsControle into an Template.
The problem is, I want to change the DataTemplate when I use my ItemsControlTemplate.
<ListView DataContext="{Binding Input}">
<ItemsControl ItemsSource="{Binding Columns}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<Label Content="{Binding ColumnHeader}"></Label>
</StackPanel>
<ListView Grid.Row="1">
<ItemsControl ItemsSource="{Binding ColumnData}">
<ItemsControl.ItemTemplate>
<!--This should be changed when I reuse my ItemsControl-->
<DataTemplate>
<Button Content="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ListView>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ListView>
You can use a Resource to set that ItemTemplate dynamically. Just provide a default Resource of DataTemplate, when you need to change it, override that resource (using the same key and place in a closer place to the control).
<ListView Grid.Row="1">
<ItemsControl ItemsSource="{Binding ColumnData}"
ItemTemplate="{StaticResource templateKey}"/>
</ListView>
Then define a resource with x:Key of templateKey like this:
<Window.Resources>
<DataTemplate x:Key="templateKey">
<Button Content="{Binding}"/>
</DataTemplate>
<Window.Resources>
Here is an example of overriding the template, in which we place another DataTemplate inside the ListView's Resources:
<ListView DataContext="{Binding Input}">
<ListView.Resources>
<DataTemplate x:Key="templateKey">
<CheckBox Content="{Binding}"/>
</DataTemplate>
</ListView.Resources>
<!-- ... -->
</ListView>
If you want to update the template at runtime, you need to use DynamicResource instead of StaticResource.

WPF - How to add textboxes to a wrap panel dynamically when number of textboxes come from a datasource

I need to add textboxes to a wrap panel but the number of textboxes come from a database. How can I do this in XAML binding instead of programmatically.
Thank you in advance
Try something like below code:
<ItemsControl ItemsSource="{Binding NumberOfTextBoxes}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding SomeProperty}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

itemscontrol mouseDragElementbehavior for new items not working

I found this solution Using MouseDragElementBehavior with an ItemsControl and Canvas by Jörg Reichardt. But it doesn't work for me.
This is my code:
<ItemsControl ItemsSource="{Binding CardCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="White" AllowDrop="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}">
<i:Interaction.Behaviors>
<is:MouseDragElementBehavior ConstrainToParentBounds="True" />
</i:Interaction.Behaviors>
</ContentControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The items are shown on the canvas but cannot be dragged or dropped. I create new items for the cardCollection in the viewmodel and the cardCollection is updated to the model via mvvm propertynotifychanged.

Bind DataTemplate after Task is finished

I'm looking for a way to bind a datatemplate which is in a resource file that my MainWindow accesses, but only after a Task that is running in the viewmodel has completed.
The idea was to load a lot of data while the view displays with a little progress area... when the progress is done... then the data should be binded... is the dependency property that allows for this?
<DataTemplate x:Key="TabsTemplate">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<UserControls:TabButton Command="{Binding Path=Tab}" Content="{Binding Path=DisplayName}" Template="{Utilities:BindableResource {Binding Path=TemplateResource}}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
Figured it out...
Tabs.GetBindingExpression(ContentControl.ContentProperty).UpdateTarget();
Works perfect after the progress is completed.

WPF: How to apply data template for items in ItemsControl if items are strings?

The ItemsControl defined below is filled with string[] WeekDays. The DataTemplate defined for ItemsControl.ItemTemplate doesn't work, i.e. the week day items are not filled with red background. How do I fix this? Thanks.
...
<ItemsControl
Grid.Row="1"
Margin="20,0,0,0"
ItemsSource="{Binding Path=WeekDays}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Background="Red" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
...
Note: string[] WeekDays is a dependency property of this control. I am not sure if this information might be relevant to finding the solution.
You need to bind the TextBox's Text property to something in order it to work. So, since the data context of the data template is the string itself the binding should be like this:
<DataTemplate>
<TextBlock Text="{Binding}" Background="Red" />
</DataTemplate>

Resources