Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
beuges
Jul 4, 2005
fluffy bunny butterfly broomstick

Drastic Actions posted:

It's called Project Rider.

And I would say if you haven't used Xamarin Studio recently, maybe check it out again. My biggest issues with it are with our web development stack (which have been unloved for years). If you want to do ASP.NET or anything like that, I would stick with VS Code. There are addons for ASP.NET core but... Yeah, not very useful IMO :(. But besides that, the debugger has gotten better, rosyln support is sweet, I like the F# support and building out Mac apps with it is cool. I'm slightly biased, but I think it works well. It's more useful than just writing Xamarin apps on Mac with it.

Drastic, since Xamarin is now free to all tiers of VS users, is there much point to maintaining Xamarin Studio going forward, or do you think Xamarin Studio will become the de-facto .net IDE for *nix, since there's probably too much WPF/native stuff in VS to make it worthwhile porting?

Adbot
ADBOT LOVES YOU

Inverness
Feb 4, 2009

Fully configurable personal assistant.
I might have asked this before but why isn't there interest in porting WPF to Mac and Linux? I know it runs on DirectX so there would be a need to replace that layer with OpenGL.

I realize it is a hugely complex technology, but if it was open source there would be some interest in porting the runtime aspects of it.

Now with .NET Core you have a valid platform that you could run it on.

Yes Mono is valid but Microsoft probably prefers their own technology.

Plorkyeran posted:

From what I've heard it was a very :microsoft: project where the VS team was forced to start using WPF despite hating it, ran into a huge number of problems, and then had to fight hard to get any of them fixed.
I suspect many of the performance optimizations in WPF are because of the VS team cracking skulls.

Ochowie
Nov 9, 2007

Inverness posted:

Plorkyeran posted:

From what I've heard it was a very :microsoft: project where the VS team was forced to start using WPF despite hating it, ran into a huge number of problems, and then had to fight hard to get any of them fixed.
I suspect many of the performance optimizations in WPF are because of the VS team cracking skulls.

I remember reading that they had to do a bunch of really ugly hacks to get WPF to work on a project as large as Visual Studio.

Inverness
Feb 4, 2009

Fully configurable personal assistant.

Ochowie posted:

I remember reading that they had to do a bunch of really ugly hacks to get WPF to work on a project as large as Visual Studio.
I want to know more about this. :allears:

Ochowie
Nov 9, 2007

Inverness posted:

I want to know more about this. :allears:

I can't find the original source but here https://www.youtube.com/watch?v=aWqg55ejoss is a video about the migration.

john donne
Apr 10, 2016

All suitors of all sorts themselves enthral;

So on his back lies this whale wantoning,

And in his gulf-like throat, sucks everything

That passeth near.
I wonder if there will ever be a good framework for building GUIs in .NET that isn't html-driven

mystes
May 31, 2006

john donne posted:

I wonder if there will ever be a good framework for building GUIs in .NET that isn't html-driven
You don't have to use XAML (I assume that's what you mean?) to use WPF, so there's no reason you couldn't use a DSL or wherever. The bigger problem is that it seems like all the underlying API's are deprecated right now. I guess the official recommendation is WPF on UWP, but nobody wants to make windows store apps. As a result, it seems crazy to put a lot of effort into Windows GUIs when anything could happen, to the point where the standard advice already seems to be to just be to make websites instead.

With .net core existing now, I'm hoping that someone will finish decent cross-platform .net QT bindings, which might well be the least lovely cross-platform option by default. It's amazing that there still isn't a decent cross-platform gui option for .net, but the gui framework options are limited in the first place, and .net certainly hasn't seemed like a realistic choice outside of windows until like 1 day ago.

mystes fucked around with this message at 02:19 on Jun 29, 2016

Drastic Actions
Apr 7, 2009

FUCK YOU!
GET PUMPED!
Nap Ghost

beuges posted:

Drastic, since Xamarin is now free to all tiers of VS users, is there much point to maintaining Xamarin Studio going forward, or do you think Xamarin Studio will become the de-facto .net IDE for *nix, since there's probably too much WPF/native stuff in VS to make it worthwhile porting?

I have zero idea about any port of Visual Studio itself. All I know is that Xamarin Studio for Mac is heavily supported. New features, like roslyn support, are being added all the time (and most of the old ones are getting fixed to work correctly :v:). And, IMO, it complements VS Code well.

Xamarin Studio for Windows? I don't know. I would say that it never did things like iOS support and it was used mostly for indie customers who did not have access to the VS plugin. I thought it was being dropped after VS went free, and I think there is talk of it at some point going away, but right now it is supported and updates are still going out. Outside of that, I don't know.

EDIT:

mystes posted:

With .net core existing now, I'm hoping that someone will finish decent cross-platform .net QT bindings, which might well be the least lovely cross-platform option by default. It's amazing that there still isn't a decent cross-platform gui option for .net, but the gui framework options are limited in the first place, and .net certainly hasn't seemed like a realistic choice outside of windows until like 1 day ago.

GTK# still does exist, as does Mono. :v:.

Drastic Actions fucked around with this message at 02:45 on Jun 29, 2016

Mr Shiny Pants
Nov 12, 2012

mystes posted:

You don't have to use XAML (I assume that's what you mean?) to use WPF, so there's no reason you couldn't use a DSL or wherever. The bigger problem is that it seems like all the underlying API's are deprecated right now. I guess the official recommendation is WPF on UWP, but nobody wants to make windows store apps. As a result, it seems crazy to put a lot of effort into Windows GUIs when anything could happen, to the point where the standard advice already seems to be to just be to make websites instead.

With .net core existing now, I'm hoping that someone will finish decent cross-platform .net QT bindings, which might well be the least lovely cross-platform option by default. It's amazing that there still isn't a decent cross-platform gui option for .net, but the gui framework options are limited in the first place, and .net certainly hasn't seemed like a realistic choice outside of windows until like 1 day ago.

Xamarin forms?

mystes
May 31, 2006

Mr Shiny Pants posted:

Xamarin forms?
I don't think it has linux support.

Drastic Actions
Apr 7, 2009

FUCK YOU!
GET PUMPED!
Nap Ghost

Mr Shiny Pants posted:

Xamarin forms?

Currently Forms supports iOS, Android, and UWP. But it's open source so if anyone wants to give a GTK/QT/WPF version a go, you can now!

Gul Banana
Nov 28, 2003

Inverness posted:

I might have asked this before but why isn't there interest in porting WPF to Mac and Linux? I know it runs on DirectX so there would be a need to replace that layer with OpenGL.

I realize it is a hugely complex technology, but if it was open source there would be some interest in porting the runtime aspects of it.

Now with .NET Core you have a valid platform that you could run it on.

Yes Mono is valid but Microsoft probably prefers their own technology.

I suspect many of the performance optimizations in WPF are because of the VS team cracking skulls.

the answer is much simpler - WPF and winforms are a competitive advantage for windows. there's a huge market for little internal business-specific CRUD apps, where people don't necessarily want to use a website. with Access, WPF, Lightswitch, etc, microsoft owns this market and they want to keep owning it

Drastic Actions
Apr 7, 2009

FUCK YOU!
GET PUMPED!
Nap Ghost

Inverness posted:

Now with .NET Core you have a valid platform that you could run it on.

Yes Mono is valid but Microsoft probably prefers their own technology.

It's more complicated then that. Mono is completely valid and is having more influence there than you think.

Mr Shiny Pants
Nov 12, 2012

mystes posted:

I don't think it has linux support.

Crap, I misremembered.

Calidus
Oct 31, 2011

Stand back I'm going to try science!
Is there someway to do something similar to this in a config file?

code:
#if DEBUG
    	x=1;
#else
   	x=2; 
#endif
edit: never mind transforms seem to solve my problem

Calidus fucked around with this message at 18:31 on Jun 29, 2016

BirdOfPlay
Feb 19, 2012

THUNDERDOME LOSER
Anybody have good suggestions on Pluralsight courses (or whatever they call them) to get a good handle on C# and WPF? Apparently, Microsoft is giving away mini-subscriptions when you sign up for a developer account, and I don't know what's good there.

In a more specific question, do ViewModels and Models basically look the same, at least in terms of fields/properties? Is it bad form to make it a "has a" relationship?

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
No idea on the PluralSight courses.

In MVVM-flavored WPF, your ViewModel contains both the data that a particular View should see and the interactions that result from performing actions on that view (e.g. clicking buttons).

Data is usually exposed with explicitly implemented properties with the setters calling some variation of "OnPropertyChanged" to let the UI know that it needs to refresh. Typical data types are C# primitives (string, int, decimal), collections types (ObservableCollection), or your own custom complex types containing more data.

Commands are usually exposed as a property of type ICommand. This is a simple interface which just defines what to do based on some UI event (and also whether or not that thing can be done). Usually this is implemented via a wrapper class around another lambda (inline function) that you define just because it's simpler.

The Model in MVVM, on the other hand, is the meat of your application. There's nothing that dictates what it should look like or what it does. The naming is confusing since a View means a specific type UI-related object in WPF, a ViewModel means a specific type of UI-related object in WPF, but the Model is just an abstract reference to "whatever the hell your application actually does". Sometimes people try to jam the functionality of their application into the methods on the ViewModel instead of explicitly creating a model. This may work for you if your application is small, but it's violating separation of concerns and makes it harder to grow your application later on.

What this results in is the ViewModel knows how to get data from the Model and transform it to be usable by the View. The ViewModel also knows how to translate button clicks into interactions on the Model. The chain of "ownership" is that the View references the ViewModel which references the Model.

Jewel
May 2, 2009

My rule of thumb is usually "The model and everything it requires and uses should completely work external to any UI". That way you can have a model that uses a database, gets stuff from the internet, reads from the disk, or whatever, and as long as it has the right interface you can plug any view into it to display the data however you want.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Jewel posted:

My rule of thumb is usually "The model and everything it requires and uses should completely work external to any UI".

Emphasizing this because I think it's really important.

epswing
Nov 4, 2003

Soiled Meat

Jewel posted:

My rule of thumb is usually "The model and everything it requires and uses should completely work external to any UI".

Yep, definitely my mentality as well.

When I think of model versus view, I ask myself "without modification, could I hook this model up to any view, be it a WPF/Console/ASP.NET/Test project?" and if yes, I'm doing something right.

EssOEss
Oct 23, 2006
128-bit approved

BirdOfPlay posted:

Is it bad form to make it a "has a" relationship?

This makes a lot of sense in many simple cases - you expose the underlying model in your viewmodel. Later, when it gets more fanciful and you actually need to transform the data instead of using it directly, it is pretty straightforward to swap it out to a viewmodel object wrapping/representing the model object.

GoodCleanFun
Jan 28, 2004

BirdOfPlay posted:

Anybody have good suggestions on Pluralsight courses (or whatever they call them) to get a good handle on C# and WPF? Apparently, Microsoft is giving away mini-subscriptions when you sign up for a developer account, and I don't know what's good there.

In a more specific question, do ViewModels and Models basically look the same, at least in terms of fields/properties? Is it bad form to make it a "has a" relationship?

If you have search there have been many conversations in this thread referencing MVVM with a number of different techniques.

kitten emergency
Jan 13, 2008

get meow this wack-ass crystal prison
I've been told there's a tool from MS or someone that you can run against your assemblies and it'll tell you how compatible they are with Mono, .NET Core, etc. My googling didn't turn anything up though - anyone here heard of such a thing?

raminasi
Jan 25, 2005

a last drink with no ice

uncurable mlady posted:

I've been told there's a tool from MS or someone that you can run against your assemblies and it'll tell you how compatible they are with Mono, .NET Core, etc. My googling didn't turn anything up though - anyone here heard of such a thing?

I've heard of a thing released by the Mono people for Mono, and I've heard of a MS thing for checking for migration to .NET Core, but I don't remember hearing about them as actually the same tool.

kitten emergency
Jan 13, 2008

get meow this wack-ass crystal prison

raminasi posted:

I've heard of a thing released by the Mono people for Mono, and I've heard of a MS thing for checking for migration to .NET Core, but I don't remember hearing about them as actually the same tool.

Hm, well, happen to remember the names of them?

Mongolian Queef
May 6, 2004

uncurable mlady posted:

Hm, well, happen to remember the names of them?

http://www.mono-project.com/docs/tools+libraries/tools/moma/

I saw this while checking out GtkSharp that was linked earlier in the thread. Sounds like what you're looking for.

EssOEss
Oct 23, 2006
128-bit approved
You want the .NET Portability Analyzer. I recommend the command-line version as the VS plugin does not work for Xamarin analysis (in my experience).

BirdOfPlay
Feb 19, 2012

THUNDERDOME LOSER
Cool, thanks for the responses! I'm not really in any danger of mixing business logic with GUI/View logic, because I've built those systems already and tested them within a simple console app. Now, I'm just trying to get a hang of linking it all together in a fun, little .NET app. Also, I unfortunately do not have search but would love to read those discussions if you can point me to a poster or the start of them.

Bognar posted:

In MVVM-flavored WPF, your ViewModel contains both the data that a particular View should see and the interactions that result from performing actions on that view (e.g. clicking buttons).

Ahh, I think this is what's throwing me off. If I'm building a single page app, the ViewModel and Model would, basically, represent the same data with a similar structure. But for more complex apps, individual pages (or what ever a different View is called) would be taking more selective bites out of the Model.


EssOEss posted:

This makes a lot of sense in many simple cases - you expose the underlying model in your viewmodel. Later, when it gets more fanciful and you actually need to transform the data instead of using it directly, it is pretty straightforward to swap it out to a viewmodel object wrapping/representing the model object.

Alright, because what I'm doing is pretty simple, it almost seemed excessive to have completely distinct classes that held the same stuff. Glad to know some initial weren't explicitly bad design decisions.

Cuntpunch
Oct 3, 2003

A monkey in a long line of kings

BirdOfPlay posted:

Ahh, I think this is what's throwing me off. If I'm building a single page app, the ViewModel and Model would, basically, represent the same data with a similar structure. But for more complex apps, individual pages (or what ever a different View is called) would be taking more selective bites out of the Model.

Yes, or depending on the complexity of your application, various UI components may have their own View Models.

kitten emergency
Jan 13, 2008

get meow this wack-ass crystal prison

EssOEss posted:

You want the .NET Portability Analyzer. I recommend the command-line version as the VS plugin does not work for Xamarin analysis (in my experience).

This is exactly what I was looking for! Thanks so much! :)

Inverness
Feb 4, 2009

Fully configurable personal assistant.
Is it necessary to use the new .NET Core Class Library project type to make libraries that use the new netstandard moniker in project.json files?

I'm asking this because I was trying to convert a PCL to the new format but when I use netstandard1.0 or netstandard1.3 for the framework, it compiles but I get a bunch of errors like this:

quote:

Restoring NuGet packages...
To prevent NuGet from restoring packages during build, open the Visual Studio Options dialog, click on the Package Manager node and uncheck 'Allow NuGet to download missing packages during build.'
System.Linq 4.1.0 provides a compile-time reference assembly for System.Linq on .NETStandard,Version=v1.3, but there is no run-time assembly compatible with win.
System.IO 4.1.0 provides a compile-time reference assembly for System.IO on .NETStandard,Version=v1.3, but there is no run-time assembly compatible with win.
System.Diagnostics.Tracing 4.1.0 provides a compile-time reference assembly for System.Diagnostics.Tracing on .NETStandard,Version=v1.3, but there is no run-time assembly compatible with win.
System.AppContext 4.1.0 provides a compile-time reference assembly for System.AppContext on .NETStandard,Version=v1.3, but there is no run-time assembly compatible with win.
Microsoft.NETCore.Portable.Compatibility 1.0.1 provides a compile-time reference assembly for mscorlib on .NETStandard,Version=v1.3, but there is no run-time assembly compatible with win.
System.Linq.Expressions 4.1.0 provides a compile-time reference assembly for System.Linq.Expressions on .NETStandard,Version=v1.3, but there is no run-time assembly compatible with win.
System.Reflection 4.1.0 provides a compile-time reference assembly for System.Reflection on .NETStandard,Version=v1.3, but there is no run-time assembly compatible with win.
System.Runtime 4.1.0 provides a compile-time reference assembly for System.Runtime on .NETStandard,Version=v1.3, but there is no run-time assembly compatible with win.
System.Runtime.Extensions 4.1.0 provides a compile-time reference assembly for System.Runtime.Extensions on .NETStandard,Version=v1.3, but there is no run-time assembly compatible with win.
System.Runtime.InteropServices 4.1.0 provides a compile-time reference assembly for System.Runtime.InteropServices on .NETStandard,Version=v1.3, but there is no run-time assembly compatible with win.
System.Security.Cryptography.Algorithms 4.2.0 provides a compile-time reference assembly for System.Security.Cryptography.Algorithms on .NETStandard,Version=v1.3, but there is no run-time assembly compatible with win.
System.Security.Cryptography.X509Certificates 4.1.0 provides a compile-time reference assembly for System.Security.Cryptography.X509Certificates on .NETStandard,Version=v1.3, but there is no run-time assembly compatible with win.
System.Text.RegularExpressions 4.1.0 provides a compile-time reference assembly for System.Text.RegularExpressions on .NETStandard,Version=v1.3, but there is no run-time assembly compatible with win.
One or more packages are incompatible with .NETStandard,Version=v1.3 (win).
NuGet package restore failed.
1>------ Build started: Project: Coroutines, Configuration: Debug Any CPU ------
1> Coroutines -> C:\Projects\CSharp\Coroutines\Coroutines\bin\Debug\Coroutines.dll
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
My project.json file:
code:
{
    "supports": {
        "net46.app": {},
        "uwp.10.0.app": {}
    },
    "dependencies": {
        "Microsoft.NETCore.Portable.Compatibility": "1.0.1",
        "NETStandard.Library": "1.6.0",
        "System.Runtime.Serialization.Primitives": "4.1.1"
    },
    "frameworks": {
        "netstandard1.3": { }
    }
}
This is the old one:
code:
{
    "supports": { },

    "dependencies": { },

    "frameworks": {
        ".NETPortable,Version=v4.5,Profile=Profile259": { }
    }
}
Edit: It seems I get the same errors even after converting the library to a .NET Core xproj. I'm puzzled now.

Edit 2: Okay it seems the problem has to do with specifying "win" in the runtimes section of my xunit test library. xunit requires that I set CopyNuGetImplementations to true in the csproj file in order to include the xunit libraries in the output directory so tests can be run. If I do this then NuGet tells me to specify the "win" runtime in the project.json file. However when I do this I get the multitude of errors I quoted earlier in the post.

Inverness fucked around with this message at 04:57 on Jul 3, 2016

Mister Duck
Oct 10, 2006
Fuck the goose

amotea posted:

Since they're dogfooding WPF for VS, why doesn't it get more love :(?

What specific things do you want to see in WPF or what are your biggest pain points? There is certainly effort being put into WPF right now (some of it mine), but we only have so much we can do at once.

raminasi
Jan 25, 2005

a last drink with no ice

Mister Duck posted:

What specific things do you want to see in WPF or what are your biggest pain points? There is certainly effort being put into WPF right now (some of it mine), but we only have so much we can do at once.

Last I checked, you still can't bind readonly properties OneWayToSource. Is there a design reason for that?

There's some built-in control functionality that I've really missed, and have had to implement hacky workarounds (or give up in despair). Some I can understand why they're not present (like multiselect in a TreeView) but things like not destroying tabs in a TabControl whenever they're deselected or being able to add a context menu to items in a TreeView seem like they should be doable without much fuss.

raminasi fucked around with this message at 17:55 on Jul 3, 2016

Inverness
Feb 4, 2009

Fully configurable personal assistant.

raminasi posted:

Last I checked, you still can't bind readonly properties OneWayToSource. Is there a design reason for that?

There's some built-in control functionality that I've really missed, and have had to implement hacky workarounds (or give up in despair). Some I can understand why they're not present (like multiselect in a TreeView) but things like virtualizing tabs in a TabControl or being able to add a context menu to items in a TreeView seem like they should be doable without much fuss.
I had a problem with a tab control, or more specifically a document pane control for AvalonDock, where performance when switching tabs was so poor because it recreated the whole tree. :wtc:

I had to make a custom content presenter in the control template that hid the content of unselected tabs instead of disposing them.

What an adventure that was.

raminasi
Jan 25, 2005

a last drink with no ice

Inverness posted:

I had a problem with a tab control, or more specifically a document pane control for AvalonDock, where performance when switching tabs was so poor because it recreated the whole tree. :wtc:

I had to make a custom content presenter in the control template that hid the content of unselected tabs instead of disposing them.

What an adventure that was.

I don't know why I said "virtualizing," because your scenario is exactly what I meant. (If you put your solution on CodeProject, I'm using it. If not, you're not the first person with that idea.)

Mister Duck
Oct 10, 2006
Fuck the goose

raminasi posted:

Last I checked, you still can't bind readonly properties OneWayToSource. Is there a design reason for that?

There's some built-in control functionality that I've really missed, and have had to implement hacky workarounds (or give up in despair). Some I can understand why they're not present (like multiselect in a TreeView) but things like virtualizing tabs in a TabControl or being able to add a context menu to items in a TreeView seem like they should be doable without much fuss.

The readonly property thing is not being changed. It's a design choice that's been repeatedly enforced over the years (I've seen several bugs in my short time that have been resolved won't fix). I can ask for the definitive reason from another member of the team who is more involved in data binding. I am relatively new to the team so I don't have all the historical knowledge on tap.

The control stuff I can bring up to the team. We've been fixing a lot of issues lately in TreeView with relation to scrolling and virtualization so I'll ask where that is headed. At current there are issues that we are addressing that take precedence over adding most features to controls since there are already a lot of professional third party controls to be had (Telerik, etc). But there is some time until the next version is released so I can take any suggestions for consideration.

Personally, I am mostly concerned with touch input these days. In that area, I can tell you that in 4.6.2 automatic invocation of the touch keyboard in Win10 RS1+ is enabled and I am also releasing some code on Github soon that will allow WPF applications to detect and respond to touch KB events (to help prevent occlusion). The later won't be part of the framework but should be simple enough to add to any application that needs it. Apart from that, we're working to modernize the touch stack in general bringing it up to the latest backing technology (WM_POINTER) so we can eliminate some of the largest complaints surrounding touch support in WPF and give us room for improvement in the future. Consequently, if you have any complaints in this specific area I'd love to hear them.

Sorry I don't have direct answers immediately, but I'll try to get a response for you by Tuesday once everyone is recovered from the long weekend here.

Inverness
Feb 4, 2009

Fully configurable personal assistant.

raminasi posted:

I don't know why I said "virtualizing," because your scenario is exactly what I meant. (If you put your solution on CodeProject, I'm using it. If not, you're not the first person with that idea.)
I've never published anything there. Here was my solution:
SelectionPresenter.cs
SelectionPresenter.xaml
DocumentPaneControlStyleEx.xaml

Gul Banana
Nov 28, 2003

i've got a "FastTabControl" subclass internally which does a similar thing, keeping a dictionary of views-for-viewmodels. it's api-compatible with tabcontrol, which is nice, but you do have to be careful to avoid memory leaks

Gul Banana
Nov 28, 2003

Mister Duck posted:

The readonly property thing is not being changed. It's a design choice that's been repeatedly enforced over the years (I've seen several bugs in my short time that have been resolved won't fix). I can ask for the definitive reason from another member of the team who is more involved in data binding. I am relatively new to the team so I don't have all the historical knowledge on tap.

if you're asking anyway - any chance we can get a fix for the thing where non-OneTime bindings to objects that aren't DependencyObjects and don't implement INotifyPropertyChanged are a permanent leak?

Adbot
ADBOT LOVES YOU

Inverness
Feb 4, 2009

Fully configurable personal assistant.

Gul Banana posted:

if you're asking anyway - any chance we can get a fix for the thing where non-OneTime bindings to objects that aren't DependencyObjects and don't implement INotifyPropertyChanged are a permanent leak?
Not sure if this is what you're talking about, but I had a problem I fixed some time ago where an object was being held onto because of DependencyObject._contextStorage. This was for a brush or something like that. I fixed the issue by freezing the brush first.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply