Displaying multiple FrameworkElement items in WPF - c#

I have custom FrameworkElement (displays 3D model, and allows to control camera), and i need to display multiple items of this type simultaneously (they should be overlapping). Items are stored in list.
For now, i can achieve that by simply placing few ContentControls in Grid, and using my FrameworkElements as Content. And it works well. But, any attempt to achieve that result for custom ammount of elements fails. I've tried to use ItemsControl, but it just doesn't work.
Is there any convenient way to display multiple items from source list, placing them in single position?
Update
Canvas and ItemsControl are simply not working for me. Even if i simply move single element there.
That means,
<ContentControl Content="{Binding DrawableElements[0]}"></ContentControl>
works well, but
<ItemsControl>
<ContentControl Content="{Binding DrawableElements[0]}"></ContentControl>
</ItemsControl>
doesn't work at all, although, it's pretty basic approach. Same goes to Canvas. I don't know, if i'm using it right, but i just can't understand, why simple ItemsControl with single element doesn't want to be displayed.
Update #2
If i have class, which has certain properties, with FrameworkElement among them, my ItemsControl, which uses list of this class instances, will work just fine with any properties EXCEPT FrameworkElement. Now i really can't understand what happening.
Note:
I'm trying to follow MVVM pattern, so there should be no direct impact on UI from code. That's why I've chosen ContentControl in first place. Otherwise i might simply add new FrameworkElements as children to simple Grid.

The problem was, thas ContentControl inside ItemsControl was setting its size params to 0 by default, so, basically, my FrameworkElements were just zero sized. I had to specify Widht and Height manually to make it visible.

Related

How to extend text selection across text blocks in a UWP app

My app has a bunch of paragraphs which are compared together. This is implemented using a generic ItemsRepeater that creates as many Grid elements as there are paragraphs. Inside each grid is a TextBlock with the paragraph number, and a RichTextBlock that contains the paragraph. The hierarchy is therefore like this:
<ItemsRepeater>
<Grid>
<TextBlock />
<RichTextBlock></RichTextBlock/>
</Grid>
<Grid>
...
</Grid>
<Grid>
...
</Grid>
</ItemsRepeater>
This results in a text selection as follows:
Only one RichTextBlock can be selected at a time. However, I would like to allow text selection of all paragraphs of the ItemsRepeater. How is that possible?
Edit
I'm open to other approaches. I've tried manually filling in a StackPanel or RichTextBlock with items. That's not a problem. However, because the numbered paragraphs need to align, I need to be able to set their height to match each other. From what I can find, only elements that derive from FrameworkElement have the ActualHeight and Height properties I need for that. However, FrameworkElements like TextBlock and RichTextBlock also do not allow multiple selection, which is the problem I'm trying to solve in the first place. Someone posted a response to a similar question about WPF, but it uses a strange solution I don't think applies.
So the question could also be framed as: how is it possible to find and set the height of a Run within a TextBlock or RichTextBlock? Using that idea, it was impossible to get/set the run height inside a paragraph. I'm not bound to using ItemsRepeater, but that has also not yielded a useful result. I'm seeking to avoid resorting to HTML/Javascript for this.
UWP does not expose enough APIs for you to do that. I have worked on a similar issue with RichEditBox on UWP and there is no good solution that I have found. But if you really want to, there are two main approaches to achieve that:
Implementing the selection yourself by sniffing the mouse events and render the selection on top of the controls. There are so many corner cases, specially if you want to have a proper accessibility tree for the control that you are building.
Alternatively, you can create a WinRT C++ project where you would have access to more APIs, build a control and render it onto a canvas that is created with your C#/Xaml app.
The good news is that you are not permitting people to edit (RichTextEdit) and it is just view (RichTextBlock) so you do not have to worry about the automatic corrections, IME, Url detection, etc.
Edit: Originally I mentioned WinRT C++, but I meant C++/CX. It might work with WinRT too, but I have not tried.

What's the difference between a stackpanel with datatemplates or a listview with listitems

I'm creating a WPF program that consumes rest api data. I want to implement lazyloading and infinite scroll on the data and programmatically create and add either custom data templates or listitems very similar to this design
I'm just confused as to which approach to take and what benefits/costs each provides
Easy choices:
Everyone uses MVVM so use MVVM.
Data Templating is a fundamental of wpf and building UI in code is not recommended - so use data templating.
You can dynamically add templates to resources by building xaml as strings. This is the MS recommended way to build any dynamic UI. Those strings can come from flat files, a database directly or a web service and you can build them by manipulating txt files or serialising controls.
A huge plus of this is you have the markup "right there". So when things go pear shaped you can paste into an experimental solution and see the errors light up in the xaml or see what the user is seeing.
If datatype associated templating doesn't suit for some reason then you could write a datatemplateselector and put your logic in there.
I'm not sure how you expect that to scroll exactly but I'd go with a listbox, some datatemplates associated with a type per view. Assuming the items can have different views - you just seem to have that "gilded" button or tag as an option.
Load your data into viewmodels with one per row.
.Add to an Observablecollection which is a public property in a viewmodel.
Bind that to the itemssource of a listbox.
They are then templated into UI.
A listbox has a scroller built in but you could re-template if you wanted to scroll using some other approach.
A StackPanel is a Panel that arranges child elements into a single line that can be oriented either horizontally or vertically.
A ListView is an ItemsControl that you can bind to an IEnumerable of objects and is used to present a collection of items.
What you should do is to create an ItemsControl with an ItemTemplate that corresponds to a scrollable item in the list. There is a basic example available here and you will find a lot more examples online.

Reusing visual tree when moving items between two ItemControls

I have two ObservableCollections in my ViewModel. Both of same generic type.
Window has two ItemsControls each with ItemsSource bound on its own ObservableCollection from ViewModel.
Both use same same ItemTemplate. This ItemTemplate is very complex user control.
It's all done by the book.
In some cases, I move item from one collection to another. UI updates correctly. However, as control is complex, it needs about 1-2sec to render when it is recreated in new ItemsControl. And since this happens on drag and drop operation, it is not user friendly.
What I would like to do is to somehow preserve existing instance of ItemTemplate from source ItemsControl and reuse it in destination. I don't know if it is even possible, I couldn't find anything about it online.
I believe setup is fairly simple, but if needed I'll write some simplified version of code (I can't share the real code).
Thanks for any help.
What I would like to do is to somehow preserve existing instance of ItemTemplate from source ItemsControl and reuse it in destination. I don't know if it is even possible, I couldn't find anything about it online.
I am afraid it is not. When you disconnect an element from the visual tree and then add it back to a different parent element at a later stage, all elements that make up the control will be re-rendered.

Binding calculations to element properties

I have a (moveable) dialog window whose initial position I want to offset from the right hand side of the app (its parent container is Canvas) based on whether some static windows are open or not.
As such I need something along the lines of this
<MyWindow Canvas.Right="{Binding Element.Width + Element2.Width}" />
This wouldnt entirely work though as if Element1 wasnt visible I wouldnt want it in the calculation. Perhaps the logical conclusion is that this cannot be done via binding alone and I'd need a property on the ViewModel.
This raises another issue in that each one of these elements (including the parent window) has its own ViewModel. Would it not be against best practices for one of these ViewModels to interact directly with Views to calculate this information?
You can use MultiBinding and calculate the total width in an IMultiValueConverter.
The ActualWidth property of an element should be 0 if it is collapsed, so you can use the element's ActualWidth property for the binding.

Extracting ListBox to separate file

So, i have quite complex ListBox, with own style and composite item templates (in every item, there are image and text, both with click events, which rises corresponding commands in global viewmodel). What would be the easiest way to re-use that ListBox?
Should i extract style only, or move it out as UserControl, or should i make new component? Everything is static (commands, markup) exept content (should be able to use different items lists).
In the perfect case, is should be (pseudocode):
Page 1 xaml
<MyListBox Content={Binding Page1List}>
Page 1 vm
ObservableCollection<Items> Page1List;
and so on for other pages.
EDIT: i found this article - that makes sence, but i think there should be easier way for that.
http://www.codeproject.com/Articles/14340/Creating-a-look-less-custom-control-in-WPF
I believe the solution you are looking for is a look-less control.

Categories

Resources