WPF ItemsControl - with no ItemContainer - wpf

I'm wanting to override ItemsControl, such that it doesn't create a container for each item, but presents them as is.
Is this possible? either through a new derived type or xaml?
Edit : To further explain, I'm wanting to bind the Canvas attached properties in the data template, as opposed to doing it in the ItemContainerStyle, but for that to work, there would have to be no container, .. such that the Canvas looks directly at the Ellipse/Rectangle.
The reason being, that the values i want to bind to may not always have the same name, as in this case, the Left property is 'Left' for types of A, but 'X' for types of B.
Im aware that i can do this with Priority bindings in the ItemContainerStyle, but would prefer to set the bindings in the data template.
Is it possible?
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type local:A}">
<Ellipse Width="25" Height="25" Fill="Red"
Canvas.Left="{Binding Left}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:B}">
<Rectangle Width="25" Height="25" Fill="Green"
Canvas.Left="{Binding X}"/>
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>

Related

Customizable content inside DataTemplate

I have the following data template for a TemplateGridViewModel. It renders a paginated grid of items where the pages can be navigable.
I want to be able to use the template with different items. Currently it just displays a label.
<DataTemplate DataType="{x:Type vm:TemplateGridViewModel}">
<Border BorderBrush="Black" BorderThickness="0.5" Margin="10 20">
<ItemsControl ItemsSource="{Binding CurrentPage}" VerticalAlignment="Stretch">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="4" Rows="2"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="0.5">
<Label Content="{Binding ManagedTemplateId}"/>
<!-- What I want is:
<ContentControl Content="{Binding Content}"/>
-->
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border>
</DataTemplate>
I imagine that I could display my interchangeable content by replacing the label with <ContentControl Content="{Binding Content}"/> (or even just <ContentPresenter/>?).
And then it would be used like this:
<ContentControl Content="{Binding IndexViewModel}">
<!--Interchangeable content here!-->
</ContentControl>
But ah, you see the problem! Content is already defined, it's the view model which is what binds us to this template in the first place!
How can I present a viewmodel via datatemplate and use interchangeable content?
When you bind an ItemsControl it sets the view model of each visual list item to the corresponding collection item, so replace the label with this:
<ContentControl Content="{Binding}" />
Then add DataTemplates for the types that are in your CurrentPage collection.

WPF/XAML Intuitive UserControl

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.

WPF : TextBox binding not working after using DataTemplateSelector/ContentTemplateSelector

I am doing a tree view UI. I used DataTemplateSelector to decide whether to display a series of textbox or combobox dynamically based on a collection of data argument.
Please note in my code. ArugumentDetailsCollection is an observable collection containing ArgumentDetails class. DefaultValue is a string property in ArgumentDetails class. Please note the property is not dependency property
The problem is that DefaultValue is not bind to TextBox. When the TextBox is displayed, it contains empty string.
Please note the Textbox is working well if data template selector is not used.
Please can someone advice ? thank you
<ItemsControl x:Name="argumentTexts" ItemsSource="{Binding ArgumentDetailsCollection}">
<ItemsControl.Resources>
<DataTemplate x:Key="TextBoxDataTemplate">
<TextBox Text="{Binding Path=DefaultValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Center"
Width="Auto"
Margin="5,0,0,0"
Padding="0"
Style="{StaticResource GridEditStyle}"
IsEnabled="True"/>
</DataTemplate>
<DataTemplate x:Key="ComboBoxDataTemplate">
<ComboBox HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Width="Auto"
Margin="5,0,0,0"
Padding="0"
Style="{StaticResource GridEditStyle}"
IsEnabled="True"/>
</DataTemplate>
<columnConfiguratorControls:ArgumentTypeTemplateSelector x:Key="ArgTemplateSelector" ComboBoxDataTemplate="{StaticResource ComboBoxDataTemplate}" TextBoxDataTemplate="{StaticResource TextBoxDataTemplate}"/>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel HorizontalAlignment="Stretch" IsItemsHost="True" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type structures:ArgumentDetails}">
<ContentControl Content="{Binding VisibleName}"
ContentTemplateSelector="{StaticResource ArgTemplateSelector}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Writing Content="{Binding VisibleName}" in your ContentControl will make the datacontext of the selected DataTemplate the VisibleName property. That's why you cannot access the DefaultValue property, since it's member of ArgumentDetails.
Change the binding to :
Content="{Binding}"
You will also need to review your ContentTemplateSelector class

How to change itemTemplate of an item in itemControl at runtime in silverlihgt 4

I have a ItemControl in silverlight 4 with a Canvas as a ItemPanel, the idea is to simulate a canvas area with drag and dop items.
ItemsControl has a ItemTemplate with a image and one button.
The idea is that when the button of itemTemplate Click the itemTemplate change.
Some of my code:
(Items Control)
<ItemsControl ItemsSource="{Binding Devices}"
ItemTemplate="{StaticResource deviceItemTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
MouseLeftButtonDown="Canvas_MouseLeftButtonDown"
MouseMove="Canvas_MouseMove"
LostMouseCapture="Canvas_LostMouseCapture"></Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
(ItemTemplate)
<DataTemplate x:Key="deviceItemTemplate">
<ContentControl>
<Grid IsHitTestVisible="True" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
</Grid.RowDefinitions>
<Image IsHitTestVisible="False" Grid.Row="0" Stretch="UniformToFill"
Width="50" Height="50"
Source="{Binding ImagePath}"/>
<Button Grid.Row="1" Content="{Binding EditarDispositivoCommand.DisplayName}" Command="{Binding EditarDispositivoCommand.Command}"></Button>
</Grid>
<ContentControl.RenderTransform>
<TranslateTransform X="{Binding X, Mode=TwoWay}" Y="{Binding Y, Mode=TwoWay}"></TranslateTransform>
</ContentControl.RenderTransform>
</ContentControl>
</DataTemplate>
I try to get that when a button in a itemTemplate is clicked the template of this item change to other template from resource.
Was that possible or i taking a bad way. Thanks a lot.
You could try using a DataTemplateSelector for Silverlight - it's not built in like WPF, but it can be achieved with some extra code.
Here is a good example from CodeProject:
http://www.codeproject.com/KB/silverlight/SLTemplateSelector.aspx
Just add an element to you view model to specify the template...
I just used the following article to do what you suggested.
I have two item templates defined for a view and can progamatically change the item template at runtime though codebehind
http://weblogs.asp.net/psheriff/archive/2010/08/25/change-templates-dynamically-in-silverlight.aspx
Hope this helps
(Sample also uses a button to change the item template)

WPF ItemsPanelTemplate not working

I'm trying to get an ItemsPanelTemplate working for a ListBox. The ListBox is used in a DataTemplate, and none of my implicit ListBox styles override the default visual style. For some reason, the ItemsPanelTemplate I'm specifiying for the control (a WrapPanel) is being ignored and a StackPanel is used instead.
This is the entire template, I can only assume there's something I'm missing which is causing this.
<DataTemplate x:Key="GroupLargeIconsTemplate" DataType="{x:Type Core:IGroup}">
<ListBox ItemsSource="{Binding Children}" OverridesDefaultStyle="True">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel HorizontalAlignment="Left" VerticalAlignment="Top" IsItemsHost="True" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto"
Width="{Binding (FrameworkElement.ActualWidth), RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<DataTemplate.Resources>
<conv:IconConverter x:Key="IconConverter"/>
</DataTemplate.Resources>
<StackPanel Margin="2" Width="100" Height="140">
<Image Source="{Binding Icon,Converter={StaticResource IconConverter},ConverterParameter=96}"/>
<TextBlock Text="{Binding Name}" TextWrapping="Wrap" TextTrimming="CharacterEllipsis" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
My guess is that the width property in the WrapPanel is making it behave as a Stackpanel.
Strange, the control template is not supposed to override the explicitly specified values, rather the opposite scenario comes to my mind...
That is, unless the control template provides a panel with "IsItemsHost" set to true. Then the ItemsPanel is ignored. Which, probably, is your case.

Resources