How do I edit a WPF DataTemplate (or similar) in VS 2010 Design view?
Is that even possible? I would love it if I could drag and drop template items (such as TextBlocks) around like I can with normal (non-template) items. Doing so makes repositioning large numbers of elements much faster and easier than going line by line with cut/copy/paste methods.
For example, I would like to edit the following code in the Design view. However, the only control I can select is the ListView. In order to make any changes to the child-objects of ListView, I have to move the cursor to it or type it out. It's very limiting.
Example XAML:
<ListView ItemsSource="{Binding}"
DataContext="{Binding}"
d:DataContext="{d:DesignData Source=SampleData/PeopleSampleData.xaml}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Border>
<WrapPanel Orientation="Vertical">
<TextBlock Text="{Binding FirstName}"/>
<TextBlock Text="{Binding LastName}" />
<TextBlock Text="{Binding Age}"/>
</WrapPanel>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Note: You might say editing 3x TextBlocks isn't too bad, and I agree, but I've shortened the code substantially for example purposes.
I think Microsoft want to sell Blend too, so they will not incorporate this functionality into the VS designer.
Related
Can't find a solution to a pretty simple UI problem:
I have a model with a Images property. The Images property holds a collection of items Image.
As for now on - I have a ListBox and binding a ListBoxItem data template to Images.Image and all good. But I have each item on a new line. Not good.
What I am willing to achieve is, lets describe as, a Listbox with Horizontal items orientation and limit of items in a row. Just like Large icons view style in Windows Explorer.
Have somebody previously implemented such a solution? Any advice will be highly appreciated.
Thank you in advance.
Use a WrapPanel (or some other appropriate Panel) as the ListBox's ItemsPanel, and disable horizontal scrolling:
<ListBox ItemsSource="{Binding Images}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" Width="100" Margin="5"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
You can set the ListBox's ItemPanelTemplate to WrapPanel, like this.
I am not sure why it is always like that - but as soon as I asked, I have found an alternative solution with usage of ListView:
<ListView ItemsSource="{Binding Images}">
<ListView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding Image}" />
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="2" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
I've spend couple of hours trying to reverse the order of listbox (bottom to top) as described on the picture:
That means that newly added items should be inserted at the top of the listbox. I do not understand that something so trivial can be so difficult to implement in wpf...
I do not want to use transient effects on panel and items itself because it causes strange behavior on scrollviewer. I can not use some sort definitions on ICollectionView because I want to use a data virtualization which provides ordered data and I have to add them as is.
This is my Listbox (ListView) definition:
<ListView ItemsSource="{Binding Collection}"
VirtualizingPanel.VirtualizationMode="Recycling"
VirtualizingPanel.ScrollUnit="Pixel"
ScrollViewer.IsDeferredScrollingEnabled="True"
IsSynchronizedWithCurrentItem="True"> <!--To manage scrolling from view model using ICollectionView.ScrollTo()-->
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListView.ItemTemplate>
<!--To auto scroll to bottom (via calling ICollectionView.ScrollToBottom()-->
<i:Interaction.Behaviors>
<Behaviors:ScrollIntoCurrentItemBehavior />
</i:Interaction.Behaviors>
<!--To pin listbox panel to bottom-->
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel VerticalAlignment="Bottom"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
Is there any acceptable solution for that? I really appreciate any help! thanks
I have fixed a couple of lines in this implementation of a VirtualizedWrapPanel.
Ok, the window in which I have put the ListView with the VirtualizedWrapPanel as the ListView's ItemsPanel shoud not be scrollable. Instead of scrolling, the user will initiate something like pages change by clicking the button. So I'll should somehow bring into view "the next portion of items" as a response to the button click.
Here is the ListView which I have described:
<ListView x:Name="StationsListView"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
BorderThickness="0"
DataContext="{StaticResource ViewModelKey}"
SelectionMode="Extended"
Grid.Row="1" ItemsSource="{Binding Stations}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<common:VirtualizingWrapPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Button Style="{DynamicResource DestinationButtonStyle}">
<TextBlock Text="{Binding FullName}"
Style="{DynamicResource DestinationStationTextBlockStyle}"
TextTrimming="CharacterEllipsis" />
</Button>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
So, how can I scroll to the next portion of items manually?
After looking through the code example from your link, I'm not convinced of the author's knowledge on the subject of virtualization. The code seems to be more complicated and less efficient than it needs to be.
I have a WPF book that explains virtualisation very well with examples and you're in luck, because someone has published it online. I'm not sure if it is legal, so I can't verify how long this link will work, but it does now: Take a look at chapter 8 in Control Development Unleashed online.
<DataTemplate x:Key="dirtSimple">
<TextBlock Margin="10,0,0,0" Text="{Binding Path=CurrentBook.Published, StringFormat=d}"></TextBlock>
</DataTemplate>
<ControlTemplate x:Key="lbWrapPanelTemplate">
<StackPanel Orientation="Horizontal" Margin="2" Background="Aqua">
<ItemsPresenter></ItemsPresenter>
</StackPanel>
</ControlTemplate>
...
<ListBox Template="{StaticResource lbWrapPanelTemplate}" x:Name="bookListBox" Grid.Row="0" ItemsSource="{Binding Path=BookSource}" ItemTemplate="{StaticResource dirtSimple}" >
</ListBox>
The list box is displaying correctly, with a beautiful "Aqua" background, and each item is boringly displayed with just a date. For some reason though the items are not flowing horizontally. I originally tried it with the Silverlight Toolkit's WrapPanel, with the same problem, but I can't even get it to work with a built-in StackPanel, so I suspect I'm missing something.
Are you trying to get selection-based behavior that a ListBox provides? If not, use an ItemsControl (and supply an ItemsPanel as below).
The reason it's not going horizontal is the ItemsPresenter ultimately has its own panel it lays out items in. It's not inserting each item separately into your StackPanel (or WrapPanel), it's putting them in its own panel
What you want to do is specify a value for ItemsPanel like so:
<ListBox ItemTemplate="{StaticResource dirtSimple}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
I have and object model, a UserProfile, that contains many ServiceProfile, each containing many CommandProfile.
I have bound this model with Telerik WPF OutlookBar:
<telerikNavigation:RadOutlookBar
ItemsSource="{Binding ServiceProfiles}"
Background="{Binding Color}">
<telerikNavigation:RadOutlookBar.TitleTemplate>
<DataTemplate>
<Label Content="{Binding Description}"/>
</DataTemplate>
</telerikNavigation:RadOutlookBar.TitleTemplate>
<telerikNavigation:RadOutlookBar.ItemTemplate>
<DataTemplate>
<Label Content="{Binding Description}"/>
</DataTemplate>
</telerikNavigation:RadOutlookBar.ItemTemplate>
<telerikNavigation:RadOutlookBar.ContentTemplate>
<DataTemplate>
<ListBox ItemsSource="{Binding CommandProfiles}" Background="Transparent">
<ListBox.ItemTemplate>
<DataTemplate>
<Button
Content="{Binding Description}"
Command="{Binding ExecuteCommand}"
/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</telerikNavigation:RadOutlookBar.ContentTemplate>
</telerikNavigation:RadOutlookBar>
This XAML code creates a OutlookbarItem for each ServiceProfile. Each OutlookbarItem presents a list of buttons as a content.
I'm not able to do the analogous job with ribbonBar: inside a single tab (referring to my UserProfile), I want to create a RibbonGroup for each ServiceProfile. Inside each Group (Service profile) there are many Ribbonbuttons, one for each CommandProfile.
But I'm not able.
I arrive to this code:
<telerikRibbonBar:RadRibbonTab
x:Name="theTab"
Header="{Binding Description}"
Background="{Binding Color}"
ItemsSource="{Binding ServiceProfiles}">
</telerikRibbonBar:RadRibbonTab>
which creates the ribbongroups, but I'm not able to control anything (title of the group, fill (via Binding) the content.
Any idea?
Thanks
Marco Parenzan
Bit late, but sorry to say but it doesn't look supported yet:
http://www.telerik.com/community/forums/silverlight/ribbonbar/headertemplate-of-radribbontab.aspx
Hello Alex Fan,
Unfortunately the RibbonBar doesn't support databinding for now. However, you can put your vote for this feature in our PITS thus increasing its priority.
In your case the best will be if you add the ribbon items programmatically.
Let us know if you need more info.
All the best,
Tina Stancheva
the Telerik team