I need to make a deep copy of a tabcontrol.
The large picture is this: I have a project which has a 300 line XAML code TabControl with 8 tabs in it which are pretty big. I also have a TreeView with different items.
When an item in that list is selected it shows the TabControl associated with it. The problem now comes that when I add an element I want to make a deep copy of the original TabControl and associate that new one to the new element (of course I'm going to erase the content in the new one). Shallow copies won't work because they are pointing to the same location in memory, so "=",IClonable are a no go. And the frustrating part is that I can't use deep copy with serialization because the TabControl is not serializable. And I can't (or should say won't) make a custom TabControl which is serializable because the TabControl is 300 line in XAML and it would be 600 line in code so it's a waste of space and time.
I've searched for this for 2 days and didn't find anything. There is no need for me to show the code because I'm looking for a general purpose Deep Copy method that can copy any type of a TabControl.
You're doing it all wrong.
You're not supposed to "copy" the UI or whatever, because UI is Not Data. You should be manipulating and copying Data Items instead of UI elements, and probably using DataTemplates to have your Data items represented on screen.
I strongly suggest that you research and learn MVVM before ever writing a single line of code in WPF.
After searching some more I initially tried a different way but it turned out to be more trouble than it's worth (tried with data binding and working more in code but still to much).
So the solution is to use XamlReader and XamlWriter. Official documentation is found here and respectively here !
To answer my question in code it would be:
Say you had this tabcontrol in XAML here:
<TabControl>
<TabItem><!--A lot of stuff here--></TabItem>
<TabItem><!--More stuff here--></TabItem>
</TabControl>
And remember this is if you have a lot of stuff (basically I didn't mention this but I'm making an interface that creates a pretty complex XML so in that TabControl I'm handling a lot of user generated data)! If you have a simple TabControl just make a custom one in code or simply use DataBindings.
So the code in the background for making a Deep Copy of that XAML defined TabControl would be this:
string savedTabControl = XamlWriter.Save(originalTabControl);
StringReader stringReader = new StringReader(savedTabControl);
XmlReader xmlReader = XmlReader.Create(stringReader);
TabControl newTabControl = (TabControl)XamlReader.Load(xmlReader);
So this is basically serialization made on xaml controls and not on data.
Related
Unfortunately Avalonia UI is still behind WPF and ListView is missing. I have found out one alternative, ItemsRepeater, but its very basic and not interactive. Apparently you can make it interactive, but I have to yet found an example that takes less than 200 lines of code and actually works. I just refuse to believe no one made something that works as simply as ListView in WPF.
I want to display List of custom data model (property A and B etc), and I'm really tempted to just use DataGrid. Will be ugly, but it will work.
You can try https://github.com/wieslawsoltes/DataBox it's very simple control with columns based on ListBox
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.
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.
This question is going to be worded awkwardly as I'm finding it difficult to word it. My code is also a bit of a mess as I'm still learning C# and probably shouldn't have delved right into WPF. This may also be why I haven't found the solution with google. Anyway...
My program has a menu with a search bar, with a tab-control that separates the program into sections and each tab-item has a user-control. The user-controls are being used to keep the XAML of the main window clean. This caused the problem where I couldn't use the search bar because it was separate from the UserControl.
As the methods in the user-control can't be static, I can only think to create it using ClassName title GetItem newItem = new GetItem(). This works! Except for the fact that nothing will be displayed on the user-control (whereas MessageBox shows me that the data exists) because (I think) I've pretty much created a new user-control to what I am displaying on the program using XAML with <local:user-control>.
I'm not familiar with data binding too much, but I've tried with no success to bind the labels, because I was under the impression that by using binds, the labels will both show the same data. Is this the case and I just implemented it wrong?
Also, I imagine that by removing the the user-control being shown using XAML and instead displaying programmatically after creating it as an object would work, but I would prefer alternatives.
The easiest way I've found to get the effect I'm hoping to achieve was this.
While I added: <local:UserControl/>,
I just needed to add x:Name="InstanceName" to get:
<local:UserControl x:Name="InstanceName"/>
With this, I can replace GetItem newItem = new GetItem(); with:
InstanceName.GetMethod();
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.