UI programming for the chronically distracted



  • So, I've decided that I need to build a couple of "portfolio apps" (actually both desktop and web apps ideally), for reasons (primarily to do with my continued employability in today's job market). But, I really don't have the first idea about how to structure a UI properly. (I don't have any idea about how to structure a question properly either, but...)

    What would be great would be an overview of what the common UI paradigms are, and which is the most lightweight framework for someone to get started with? I'm not really too fussed about programming language (C++/C# may have a slight edge, but anything JS/SML/Haskell/Rust/Ruby might be fine), but I do want to be able to data-drive the building of my UI from XML/YAML/JSON file(s).

    TL;DR: Please upload "UI Programming" into my brain so I can Doing it Right™ with minimal actual effort on my part. My homework is due on Tuesday.

    I guess before I write a book, I want to try and figure out the following?

    1. Is MVVM the best way to design and implement UIs?
    2. Is there a good MVVM tutorial which takes you through the whole process?
    3. Are there other valid approaches to UI design?
    4. Are there good tutorials for other approaches?
    5. What's a good general-purpose technology to use to build UIs?
       

    Here's a few random things I've investigated so far, feel free to point and laugh at how lamentably inaccurate my current opinions are.

    ##MVVM
    This is probably the one thing I really need to get my head around. Stands for Model/View/ViewModel, which isn't confusing at all. Replacement for the "classic" Model/View/Controller and is better for reasons? (Controllers are rubbish?)
    I think I sort of get this: Model is your business data/business logic, the View is widgets and stuff on the screen, and the ViewModel is stuff that's sort of neither one nor the other, and communicates between the two. But I don't really know what the hard & fast criteria are for deciding what goes where. I would love to find a "MVVM for total n00bs" tutorial which walks you through designing a simple UI and breaking it down into 'this goes in the Model, this goes in the View, etc..." Bonus points if they show you how to build a simple UI and then add new widgets to it as the design changes.

    I would guess that this is what 90% of people think of when they say UI programming (XAML, WPF, PRISM etc), but seems maybe a bit over-engineered - you need three classes for every widget? Are there any "MVVM-lite" paradigms out there?
    Probably a good tutorial on MVVM (or related paradigms) would be the #1 takeaway from this topic for me.

    ##Shoes
    Found this looking for "simple UI". It's written in Ruby, and seems easy enough to get started, although apparently this passes as a manual. Representive sample:

    Indeed.
    No mention of any seperations of layers here, seems like you just write your widgets and their control logic directly together in the same file, so maybe this wouldn't scale to a complex UI...

    Differential Execution

    This is an interesting technique, although the majority of the online documentation seems to consist of an answer to a single StackOverflow question (although there are a couple of youtube videos as well, but it's apparently the work of a single guy). Seems to be basically you build a state machine where each widget is handled by a single method, and you use special macros to indicate the logic for adding/removing/positioning widgets. Probably not a million miles away from Shoes actually, although written in C++ rather than Ruby. Again, there doesn't seem to be a clear separation of View from Model. (Due to use of macros, it might be a bugger to data-drive as well...)

    Qt

    I guess Qt has everything you'd need to build a complex modern UI for a cross-platform app (does it do Android/Web stuff too?) So it might be worth getting up and running with it for that reason alone. Don't know if it supports MVVM out of the box though? It also seems to be an intimidatingly large library to get to grips with.

    There are other 'widget libraries' besides Qt out there as well (wxWidgets, FLTK, Fox Toolkit etc...)


  • FoxDev

    If you're thinking C# and MVVM, then WPF is a good bet; it's a natural fit for both. And there's built-in support for data binding too. Be warned though: XAML is pretty verbose; use visual designers as much as possible.



  • I can't answer your question about what is best, because I really don't know myself. I've mostly done terrible C++ apps with MVC, then moved to terrible C# apps with WinForms. Just like you, I started learning WPF and MVVM to see if I could be less terrible.

    MSDN is the obvious place to start learning MVVM. When you get into your first project, you'll find yourself repeating a good bit of boilerplate code, so you might want to look for frameworks that have written the boring stuff for you. MVVM Light was what I started with.

    FWIW, MVVM was too difficult for me. I've fallen back to writing terrible C# WinForms apps again.



  • @tar said:

    but I do want to be able to data-drive the building of my UI from XML/YAML/JSON file(s).

    Why?

    @tar said:

    Is MVVM the best way to design and implement UIs?

    I much prefer to simply thing of the entire UI as the view layer. If you're going to use the MVC paradigm, which personally I'm not a fan of. For the reasons you point out further down, you spend more time thinking, "what layer does this go in?" then you do writing practical code.

    For example, say you're building a charting app. You want to allow charting for any date range and any combination of dimensions. What's the model? Well... there is no model. At least no model you can determine in advance, it all depends on what the user decides to chart. So how do you fit that into MVC? Well you just... uh... have a controller and ignore the model and call it good? I guess? And that's just one of a million examples of things I've wanted to do that don't fit in the MVC paradigm.

    @tar said:

    What's a good general-purpose technology to use to build UIs?

    I think you need to nail down the language first.

    For example, in C# you have WinForms/MonoForms (or whatever Mono's version of same is called. You have XAML. And for web projects, you have WebForms, or you write your app as an API and use any of a million JavaScript front-end frameworks.

    @tar said:

    I would guess that this is what 90% of people think of when they say UI programming (XAML, WPF, PRISM etc), but seems maybe a bit over-engineered - you need three classes for every widget?

    That's why I'm a fan of treating the entire UI as the view. It reduces the number of abstractions. You'll going to find some militant people who are like, "there should NEVER be any code in a WinForms/WebForms code-behind! It should only call into other classes!" but you know what? Screw that attitude.

    @tar said:

    I guess Qt has everything you'd need to build a complex modern UI for a cross-platform app (does it do Android/Web stuff too?) So it might be worth getting up and running with it for that reason alone. Don't know if it supports MVVM out of the box though? It also seems to be an intimidatingly large library to get to grips with.

    I understand Qt has a "layout the window from an XML file" feature that you seem to want. So maybe that's a good choice.



  • For demos with mvvm, c# asp.net using vnext is really clean and easy to set up.


  • Banned

    @blakeyrat said:

    I much prefer to simply thing of the entire UI as the view layer.

    +1. We don't need no stinky patterns!



  • @blakeyrat said:

    You'll going to find some militant people who are like, "there should NEVER be any code in a WinForms/WebForms code-behind! It should only call into other classes!" but you know what? Screw that attitude.

    Agreed!



  • @RaceProUK said:

    use visual designers as much as possible.

    Eeeek, no. Nonononono. Don't do that, unless you want to land on TDWTF.

    By my experience with VS default designer, they're pretty horrible in figuring out what you want - so if you put a button "there", "there" being in the center of your window, it will happily slap a "Margin=165.25 244.5" (or however they call it, IDR) and break your stuff once the user wants to resize.

    Yes, XAML is awfully verbose, but it's not rocket science either. Most of the time you'll want a simple grid (and, unlike HTML, XAML actually provides a proper container for that, instead of table abuse), and then to lay out the controls inside that grid. Aside from the damn ColumnDefinitions, there's not even that much verbosity.

    @NedFodder said:

    FWIW, MVVM was too difficult for me.

    It's not too hard to figure out, but it pretty much takes over your whole project, which I'm not a fan of. All the DependencyProperties, ICommands, IValueConverters, etc. are a) verbose and b) throwing the regular programming paradigms out of the window. So if you want to do MVVM "the proper way", prepare for a bit of figuring out how to do simple tasks that you'd normally just slap in an OnClick handler.

    @blakeyrat said:

    For example, say you're building a charting app. You want to allow charting for any date range and any combination of dimensions. What's the model? Well... there is no model.

    Well, your model would be the data you're trying to chart. It doesn't have to be a full-fledged coding layer - a model might as well be a DB and a thin layer to get the data from the tables into objects. Hell, you can even pass back OracleDataReaders to the controller if you're so inclined.

    It gets worse if you try to do some advanced data binding, but in general, yep, you can just "ignore the model", so to speak.

    @blakeyrat said:

    And for web projects, you have WebForms, or you write your app as an API and use any of a million JavaScript front-end frameworks.

    And MVC, which kinda-but-not-quite fits into the latter. Also, personally I think WebForms is a Frankenstein's monster-level abomination, and I have yet to see a WebForms app that worked well with more AJAXy stuff.

    @blakeyrat said:

    You'll going to find some militant people who are like, "there should NEVER be any code in a WinForms/WebForms code-behind! It should only call into other classes!" but you know what? Screw that attitude.

    The UI code in code-behind is fine, sometimes even necessary unless you want to make your app a total abstractions clusterfuck. What shouldn't really be there is business logic.

    It seems to gets much worse in WPF, in which the common design pattern is to have zero code behind whatsoever, and you spend three hours figuring out how the fuck do you make a button click activate another button while staying three layers removed from the view.



  • @Maciejasjmj said:

    By my experience with VS default designer, they're pretty horrible in figuring out what you want - so if you put a button "there", "there" being in the center of your window, it will happily slap a "Margin=165.25 244.5" (or however they call it, IDR) and break your stuff once the user wants to resize.

    Huh?

    In VS' designer, window resize behavior is controlled by the Anchor property. It works fine. I don't know what "your experience" is, but it's pretty limited if you didn't know that.

    @Maciejasjmj said:

    and then to lay out the controls inside that grid.

    From my experience, very very few UIs are laid out in a grid.

    @Maciejasjmj said:

    Also, personally I think WebForms is a Frankenstein's monster-level abomination, and I have yet to see a WebForms app that worked well with more AJAXy stuff.

    WebForms is fine for what it's designed to do. If you're (trying to) make single page AJAX sites in it, you're way out of its bailiwick.


  • FoxDev

    @Maciejasjmj said:

    By my experience with VS default designer

    There's your problem; you should be using Blend



  • I have some experience with WPF. A large school project and a few just-for-testing throwaway apps, one of which suddenly turned into a real production-level app.

    I knew MVVM existed, but it always seemed too abstract and ivory tower like. And since I was either learning or making who-cares quality level UI-s, I just built the standard code-behind crap, with a "business logic" layer consisting of a bunch Smurf-Whatever-Manager style classes.

    It worked well enough at first, but once I started trying to turn my last throwaway app into a "real" project, all sorts of problems started emerging. Code-behind grew too large and unmaintainable. Threading became an issue. Things would block randomly because I didn't properly isolate UI and background threads. Crashes. It was a hell to maintain. Luckily, the project fell through, so I could just sweep it under the rug and pretend it never existed.

    Bottom line, look into MVVM. There's probably a good reason UI pros are championing it.



  • @blakeyrat said:

    I don't know what "your experience" is, but it's pretty limited if you didn't know that.

    Admittedly, I didn't spend too much on it when I could just write XAML, which I would have to fall back to anyway for anything more complex. Your example still requires you to fiddle with property sheets instead of just D&D the controls and having them fit, but okay, I'll give you that.

    @blakeyrat said:

    From my experience, very very few UIs are laid out in a grid.

    From mine, almost all of them can be modeled as such (with some subgrids and col/rowspans). Technically something like a DockPanel might be more suited for this, but the grid would do the job too - instead of docking something to the top, you make a grid row.

    I could even model Discourse that way if I squinted my eyes a bit, though that might not be the best example.

    @blakeyrat said:

    If you're (trying to) make single page AJAX sites in it, you're way out of its bailiwick.

    I get that it's not suited for single-page apps, but even simple JS helpers can get out of your reach really fast, since you technically aren't supposed to have any idea about the resulting HTML. It's also ugly as sin, and the ViewState is an obvious hack to make the webpages seem stateful when they're really not.

    @cartman82 said:

    I knew MVVM existed, but it always seemed too abstract and ivory tower like.

    It's not per se, but Microsoft's WPF flavour of it certainly has a few levels of abstraction too much. I much prefer their MVC model found in ASP.NET.



  • @Maciejasjmj said:

    Your example still requires you to fiddle with property sheets instead of just D&D the controls and having them fit, but okay, I'll give you that.

    You don't have to use property sheets if you don't want. You can just edit the form's description directly in its C# code. Not very different from editing XAML, except it's compiled into the final assembly.

    @Maciejasjmj said:

    It's also ugly as sin, and the ViewState is an obvious hack to make the webpages seem stateful when they're really not.

    It joins every other method of making webpages seem stateful when they're really not, all of which are obvious hacks.

    But I digress.



  • @blakeyrat said:

    You can just edit the form's description directly in its C# code.

    Huh. I've always thought it actually keeps the data separately and just generates the backing class based on a T4 template or something like that, but apparently the designer does actually parse the code.

    It's still hardly "visual design", but pretty clever, I admit.



  • @blakeyrat said:

    @tar said:
    data-drive the building of my UI...

    Why?

    The most compelling reason I can think of would be if you want your app to update itself automatically over the internet, then you have the option of changing the UI layouts without needing to do anything complex like load/unload DLLs or restart the app, just pull down the new layout data and re-render the UI. It also might be a little quicker to iterate on the UI during development if you don't need to recompile between edits. It could be open to debate whether the benefits are worth the additional complexity though...



  • I THINK you can do that with WPF and loose XAML. However that probably means going full-on MVVM with Command-ing.

    Looks like someone started a framework that can do that.



  • Ok, my experience with mvvm is from a couple of half-finished winrt apps, discouser (which I got bored of when I realized that there was basically no way I could escape from showing html in xaml, for which no good options exist, and that there was no satisfactory way to implement marking posts as read, which the discourse team have made a fundamental part of being able to post on discourse forums) and a simple drum machine which I'm still working on.

    My observations are from the perspective of an amateur trying to use the pattern to get what I want done, rather than any kind of best-practices guide. I found that mvvm (and presumably mvc too, which I understand is exactly the same, except microsoft had to make up their own acronym so that buzzword-happy hiring managers didn't get confused) is a pretty useful way of thinking about projects, that lends itself towards well-organized code. My understanding is:

    Models — hold data that is persisted between runs. I was using sqlite.net, which is just the thinnest possible layer of strong-typing over sqlite1. My models had no functionality, they just held data that would be returned by sql queries. Other heavyweight frameworks tend to put the entire orm in the model layer, meaning that, for instance, changes to the database could be propagated back to the app via the object layer. I dislike that approach.

    Viewmodels — hold data that isn't persisted. There's a lot of talk about not getting your views caught up in your viewmodels, as if you could move to an entirely different framework without having to rewrite them, that's basically just a pipe dream for me, due to how hard xaml can be to work with. Basically, viewmodels are just there so that the views have something to bind on to.

    Data Context — one of the mvvm tutorials suggested using a datacontext object to connect viewmodels with models. I liked the idea and ran with it. Basically, this is where the magic dependency injection happens. Tbh, my discouser datacontext ended up as a bit of a god-object/big ball of mud2. My excuse is that I was still figuring out what I wanted it to do, and that would refactor it as soon as I settled on a good design.

    Views — markup and databinding only. Xaml, as I'd assume any good databinding framework would, does a very good job of convincing you not to have any state in the ui itself. Every single thing that happens, every data item that is displayed, happens via the viewmodel. My hypothesis is that if you want to learn the mv.+ pattern, you need to choose your framework, try to build your views, then everything else will just fall into place as the most natural way to organize your backing code.


    1 Example:

     using SQLite;
    using System;
    
    namespace Discouser.Model
    {
        [Table("Posts")]
        class Post : IModel
        {
            [PrimaryKey]
            public int Id { get; set; }
    
            [Indexed]
            public int TopicId { get; set; }
    
            [Indexed]
            public int PostNumberInTopic { get; set; }
    
            public int UserId { get; set; }
    
            [NotNull]
            public DateTime Created { get; set; }
    
            public string Text { get; set; }
    
            public string Html { get; set; }
    
            public bool Deleted { get; set; }
    
            [Indexed]
            public int? ReplyToPostInTopic { get; set; }
        }
    }
    

    2 I have a method in my datacontext that looks like this:

    public async Task<T> Transaction<T>(Func<SQLiteConnection,T> action)
    {
        T result = default(T);
        await _db.RunInTransactionAsync(db => result = action(db));
        return result;
    }
    

    and then my viewmodels do shit like this:

    var postList = await _context.Transaction(Db => Db.Table<Model.Post>()
        .Where(t => t.TopicId == _model.Id)
        .OrderByDescending(t => t.Created))
        .ToList();
    

    I was going to refactor it eventually, I swear.



  • @NedFodder said:

    [MVVM Light][2] was what I started with.
    [2]: https://mvvmlight.codeplex.com/

    I guess for the sake of starting somewhere, I'll take a look at the documentation page for this first. They actually do seem to have three or four hours of video, and probably as much reading material on MVVM, so if nothing else this should give me a better basic understanding.



  • @Buddy said:

    My understanding is:

    Models — hold data that is persisted between runs. I was using sqlite.net, which is just the thinnest possible layer of strong-typing over sqlite<sup>1</sup>. My models had no functionality, they just held data that would be returned by sql queries. Other heavyweight frameworks tend to put the entire orm in the model layer, meaning that, for instance, changes to the database could be propagated back to the app via the object layer. I dislike that approach.

    Viewmodels — hold data that isn't persisted. There's a lot of talk about not getting your views caught up in your viewmodels, as if you could move to an entirely different framework without having to rewrite them, that's basically just a pipe dream for me, due to how hard xaml can be to work with. Basically, viewmodels are just there so that the views have something to bind on to.

    Data Context — one of the mvvm tutorials suggested using a datacontext object to connect viewmodels with models. I liked the idea and ran with it. Basically, this is where the magic dependency injection happens. Tbh, my discouser datacontext ended up as a bit of a god-object/big ball of mud2. My excuse is that I was still figuring out what I wanted it to do, and that would refactor it as soon as I settled on a good design.

    Views — markup and databinding only. Xaml, as I'd assume any good databinding framework would, does a very good job of convincing you not to have any state in the ui itself. Every single thing that happens, every data item that is displayed, happens via the viewmodel. My hypothesis is that if you want to learn the mv.+ pattern, you need to choose your framework, try to build your views, then everything else will just fall into place as the most natural way to organize your backing code.

    I can only like once, so QFU!
    I agree with the parts of this that I understood before I read it, and the other parts were useful for laying down some nice concrete terms for deciding where different parts of a solution should live.
    I think I probably need a bit more time to figure out exactly what DataContexts are for though—I shall probably take a look at your code at some point... :)


  • BINNED

    @tar said:

    I guess Qt has everything you'd need to build a complex modern UI for a cross-platform app (does it do Android/Web stuff too?)

    To give a viewpoint from someone who fiddled with it. Caveat emptor: most of my work in Qt was services, not so much GUIs, but I did some light UI development.

    If you want to go the classic widget route, use the designer. Seriously. It produces XML, yes. It's also based around layouts. Don't just slap controls around, you'll get an unresizable mess with absolute coordinates. Remember to put everything in some kind of layout and you're golden. It does limit you to desktop platforms though (Win, Linux, Mac). From what I heard, widgets technically do work on mobile, but they look like ass.

    For mobile support you'll want to go with Qt Quick, which is closer to what you're looking for I guess. Basically, you define your models in C++ (although, technically, you can avoid C++ completely if you're dealing with data from JSON / XML). The UI and logic is written in QML. It's a declarative language, looks kinda like CSS at a first glance.

    This is where it gets confusing to explain, and it's past 4 AM so it might look incoherent: you can catch / emit events and pull data from your C++ models using JavaScript. You can freely mix JS into QML. Or, you can pass events to your C++ backend. It's really a matter of what you want to do, really. If you want constant, stable models on which you can slap on different pieces of UI, do all the heavy lifting in C++, otherwise event processing in JS works just fine.

    For switching between different "screens" of you application there is a state machine engine. You can define what triggers the state, code executed on transitions (including animations if you want them), all that good stuff. You can just do it all by hand, but the state machine really helps.

    As for native feel... Widgets will be fine on desktop. QML has styles for desktop platforms and Android (so far). It all looks good and as close to native as you'll get with something multiplatform, IMHO. You should still separate your desktop UI from mobile UI (different conventions and all that), but if you make C++ handle all the data shuffling it should be relatively easy to knock out multiple UIs in QML depending on the platform.

    I can try to be more coherent and share some code later if you want, right now I think I need some sleep...



  • @Onyx said:

    If you want to go the classic widget route, use the designer. Seriously. It produces XML, yes. It's also based around layouts. Don't just slap controls around, you'll get an unresizable mess with absolute coordinates. Remember to put everything in some kind of layout and you're golden. It does limit you to desktop platforms though (Win, Linux, Mac). From what I heard, widgets technically do work on mobile, but they look like ass.

    Interestingly, it was reading about Qt Layouts, which prompted me to add it to my "list of random UI stuff research material". I've currently got some FLTK widgets wrapped but I don't think FLTK has anything approaching Qt in this area. (Then again Qt's 'online installer' is ¾ the size of the entire FTLK source tree...)

    I definitely want to play with the Designer though. If nothing else, it should contain good ideas I can steal... :)



  • @tar said:

    Then again Qt's 'online installer' is ¾ the size of the entire FTLK source tree...

    Maybe I can get away with installing just the source code...

    Bugger.

    Filed under: how do I making my tablet larger?



  • I'm going to do a bit of a xaml braindump. I'm no expert; most of my xaml learning has been of the “how do I solve this problem, so I can get back to the actual coding” variety. The obvious first place to start would have been to learn the xaml syntax. I either didn't do this at first, or I tried to understand it and failed. I'm better now.

    The xaml document exactly corresponds to a graph of clr objects. The parser runs forward through the document, instantiating each object as it parses it. When it hits a tag like <Button Click="OkButton_Click">Ok</Button>, it instantiates a Button UIElement as a child of the element it was contained in1, then it assigns the "OkButton_Click" string to the Click property, using some kind of default conversion to convert that string to the event handler with the same name, then it assigns the "Ok" string to the button's Content property, same as if you'd typed <Button Click="OkButton_Click" Content="Ok" />. It's not always going to be a property named Content that the contents of the tag will be assigned to; each class can nominate exactly one property that any objects that are instantiated inside it will be added to. You normally don't need to ask which one; it's obvious from context.

    If you want to assign something other than a string to a property, you have two choices: property element syntax or markup extensions.

    Property element syntax:

    <Button Click=OkButton_Click>
      <!--​ Yet another way to set the same property; this tag is obviously redundant, but to set a different property you can do it like this -->
      <Button.Content>
        <!--​ The Content property of the button will be set from the OkButton_Text property of the associated viewmodel -->
        <Binding Path="OkButton_Text" />
      </Button.Content>
    </Button>
    

    Markup Extension:

    <!--​ Positional parameter -->
    <Button Click="OkButton_Click" Content="{Binding OkButton_Text}" />
    <!--​ Named parameter -->
    <Button Click="OkButton_Click" Content="{Binding Path=OkButton_Text}" />
    

    You can do this because Binding inherits from MarkupExtension.

    Property element syntax is weird because you can have tags that are instantiating objects next to tags that are specifying properties that are to be assigned to, and it's only the . in the name of the tag that tells the difference. Also weird that the class before the period doesn't need to be the same as the class it is being set on: you can set an attached property on a class, which wpf will keep track of, and allow members of that other class to access. It'll make more sense with an example (not that xaml Grid controls make sense in general, but whatever):

    <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
      </Grid.RowDefinitions>
    
      <TextBlock Grid.ColumnSpan="2" Grid.Row="0">2005 Products Shipped</TextBlock>
      <TextBlock>
        Quarter 1
        <Grid.Row>1</Grid.Row>
        <Grid.Column>0</Grid.Column>
      </TextBlock>
    </Grid>
    

    1More accurately, it assigns or adds2 it to whatever property you've placed it within.
    2Properties that inherit from IList get sugared such that you can create several objects inside them and each one gets added to the list.


    Next section: the editor. As some people have mentioned, the visual editor is a large part of using xaml. I suppose you could just write xaml directly, if you know what you're doing, but given xaml's learning curve...

    The workflow I use is to do most of my changes directly to the xaml pane of the design view, then check the design pane to see if I've done the right thing. The 'Toolbox', to the left of the design view is the first place to look for ui elements to use, you can drag & drop them onto the design pane or the xaml. With an element selected, the properties pane to the right shows what properties could be set or changed for that element.

    Now, if you are using the visual editor, as you start binding things up you need the viewmodels they are bound to to hold some content, or things won't display. If you've made the mistake of opening Blend, you might have found the option where it can generate some sample viewmodels for you, and set all of the properties to lorem ipsum or whatever. Don't fall for it: it just creates a hellish nightmare3 of static xaml content that you will have to update every time you refactor. The lazy way to supply your design with sample content is to define a no-arg constructor which will populate the viewmodel with sample data, and set the view's datacontext (view.Datacontext != viewmodel.DataContext) to an instance of your viewmodel

    <Page.DataContext>
        <viewmodel:MainPageViewModel />
    </Page.DataContext>
    

    then in the codebehind, find the page constructor and instantiate the class for real and assign it to the DataContext property, overriding the dummy setting when the program runs. When you're done developing, you can remove the part of the xaml that sets the page datacontext to sample content.

    public MainPage()
    {
        InitializeComponent();
        var dataContext = new DataContext("db connection string");
        this.DataContext = new MainPageViewModel(dataContext);
    }
    

    3Or a nightmarish hell. The point is: winners don't do xaml.


    Binding: My biggest problem with binding used to be that I just didn't know wtf any of the syntax I was using meant. Typing this up, I've finally managed to connect the dots, now I'm not sure what more there is to add. I suppose there are some parameters to the Binding object that could be useful:

    • Mode: You've already seen one way binding, where the button text was set from a property, another mode is TwoWay, where the property on the viewmodel will be set when the content or state of the control changes. For the most part, it seems to ‘just work’: you can bind a textbox to an int and it'll just swallow any errors when the user types nonsense into it.
    • Path: Resolves to a property of the current element's datacontext (which will == it's parent's datacontext unless otherwise set)
    • ElementName: Allows you to override the datacontext with a uielement. Mostly useful for binding to the selected item of a ContentControl.
    <ScrollViewer name="sv" ItemsSource="{Binding Items}" />
    <StackPanel name="infopane" DataContext="{Binding SelectedItem, ElementName=sv}" />
    

    Items is a collection of viewmodels. Children of the info pane will have the Item viewmodel corresponding to the currently selected row in the scrollviewer as their DataContext.

    • Converter: most common use I've found for it has been to bind element visibility (which is an enum) to a boolean property on the viewmodel. You need to write a class that implements IValueConverter, then the simplest way to access it is to add it to your top level resources dictionary, then use the StaticResource markup extension to access it. Otherwise you're looking at
    <UIElement.Visibility>
      <Binding>
        Path
        <Binding.Converter>
          <local:BooleanToVisibilityConverter />
        </Binding.Converter>
      </Binding>
    </UIElement.Visibility>
    

    four levels of angle brackets for something that could have taken

    <UIElement Visibility="{Binding Path, Converter={StaticResource VisibilityConverter}}" />
    

    two levels of curlies4. Don't forget that you can set properties on the converter object (saves a bunch of messing about with Binding.ConverterParameter properties and converting strings to ints). This is what my top level resource dictionary looks like:

        <Page.Resources>
            <local:NumericScaleConverter Scale="0.00048828125"  x:Key="SamplesToPixelsConverter" />
            <local:BooleanInverter x:Key="BooleanInverter" />
            <local:BooleanToVisibilityConverter x:Key="VisibilityConverter" />
            <local:BooleanToVisibilityConverter Invert="true" x:Key="InverseVisibilityConverter" />
        </Page.Resources>
    

    4Naturally, the best parts of xaml are the parts that look like json.


    Commands: The best way to do something when the user presses a button is to implement ICommand (I think wpf provides an implementation?), and bind the Button.Command property to a property on your viewmodel that returns an ICommand instance. Gives you button disablement practically for free too.


    INotifyPropertyChanged: The most annoying thing about xaml is that it doesn't just telepathically know when a property on your viewmodel has been changed. You need to implement INotifyPropertyChanged, preferably on ViewModelBase, and raise PropertyChanged("NameOfProperty"); in every setter. Probably if you're developing for desktop there are some heavyweight frameworks that can simplify it for you, but I've never used a framework, so I can't tell you (if I were to use one, it'd probably be Okra).

    Raising the event from a non-ui thread will throw. I think the best time to get hold of the ui dispatcher is in the viewmodel ctor. You can save the dispatcher in your viewmodelbase, and any methods that might be called from a different thread can use it to run themselves in the right context. Although I don't seem to have done that in discouser, so I'm not 100% sure that all works the way I'd expect; maybe there are some problems with it that I don't remember any more.


  • Java Dev

    @Maciejasjmj said:

    figuring out how the fuck do you make a button click activate another button while staying three layers removed from the view.

    If button clicks activate other buttons I think you've got business logic in your UI. You probably want to switch on some backing property instead.

    Why is button A causing button B to activate? Probably because you're switching to some different operation mode, or because some backend feature is now active. So toggle on that.

    This logic should be in option B, which needs to hook this in the backend somehow. How to do this in your favourite framework is left as an exercise to the reader.


  • FoxDev

    @tar said:

    Filed under: how do I making my tablet larger?

    got a microSD card slot on that thing?



  • @accalia said:

    got a microSD card slot on that thing?

    I do, but a microSD is a shockingly inappropriate replacement for a HD in most situations...



  • Uh, at the risk of being too critical in the Coding Help category, are you 100% sure you want to use a windowing framework whose installer draws a window like this?

    [img]http://what.thedailywtf.com/uploads/default/14923/545e22bb93b05f07.png[/img]


  • Discourse touched me in a no-no place

    Maybe he likes wasting an ocean of space and ending up with having everything in a tiny little area that is hard to use and so which requires far more scrolling than any sensible person would ever want? Some people are a bit dumb…



  • Yeah and you know what's awesome? A header that's about 3 times taller than it should be, and having buttons that manipulate a listbox being absolutely in no way visually related to the listbox. Not even vaguely lined-up with it. Oh and your window's icon? You don't need it in the top left corner. Just put it where ever. It's a casual, Lake Woebegone, kind of window layout.

    (You know what's really disgusting about that header? In Windows Vista/7 it'd be a huge slab of Aero translucency, and look even more awful. TortoiseSVN for a long time made that same mistake, it had oodles of windows with acres of Aero translucency. Might still, I haven't used it in a few years.)


  • Discourse touched me in a no-no place

    Qt: How to look shit on many platforms at once!



  • @blakeyrat said:

    a window like this?

    @dkf said:

    Maybe he likes wasting an ocean of space

    It's actually resizeable, and is probably acceptable if maximized— I tried to shrink it down to as small as I could before taking screenshots, so my post wouldn't be larger than the screen. I am TRWTF.



  • @tar said:

    It's actually resizeable, and is probably acceptable if maximized— I tried to shrink it down to as small as I could before taking screenshots, so my post wouldn't be larger than the screen. I am TRWTF.

    That solves one of the like 5 problems we pointed out.



  • All the complaints about the title bar probably stil apply...


  • FoxDev

    @tar said:

    All the complaints about the title bar probably stil apply

    QFT


  • FoxDev

    @tar said:

    I do, but a microSD is a shockingly inappropriate replacement for a HD in most situations...

    granted, but if it's your only option.... ;-)



  • @tar said:

    The most compelling reason I can think of would be if you want your app to update itself automatically over the internet, then you have the option of changing the UI layouts without needing to do anything complex like load/unload DLLs or restart the app, just pull down the new layout data and re-render the UI. It also might be a little quicker to iterate on the UI during development if you don't need to recompile between edits. It could be open to debate whether the benefits are worth the additional complexity though...

    You want to entirely change the architecture of an application so that you don't have to invest the one-time effort to figure out auto-update? I assure you it's easier than you think, even if you roll your own solution.

    As for saving a compile - do you really think that 5 seconds will make a difference?


  • BINNED

    How is it supposed to look on Win8? I'm serious, I have no clue. I used the thing for like 45 minutes in total, and all I did was set some stuff up in control panel. Are you supposed to have the Back / Next buttons in the footer? Because I saw a lot of places where they are placed at the top as in the screenshot? Where are they supposed to be, in the titlebar itself?

    As a reference, this is what it looks like on my system:

    Which to me looks reasonable, given the platform conventions.



  • That also reveals to me that the window can be maximized, but lacks the Maximize and Minimize widgets in the title bar. IT ONLY RAISES FURTHER PROBLEMS!



  • @Onyx said:

    How is it supposed to look on Win8? I'm serious, I have no clue. I used the thing for like 45 minutes in total, and all I did was set some stuff up in control panel. Are you supposed to have the Back / Next buttons in the footer? Because I saw a lot of places where they are placed at the top as in the screenshot? Where are they supposed to be, in the titlebar itself?

    Here's a bog-standard Microsoft installer wizard I happened to have sitting in my Downloads folder:

    The button placement is correct for Windows. (That said, I think Windows has stupid/wrong/dumb button placement there. Cancel shouldn't be right next to Next, that's retarded.)

    EDIT: also, interestingly, your Linux version of the box looks more like the Windows version should look. Weird. (Still lacks Maximize/Minimize/whatever window sizing widgets you have in your particular Linux OS, though.)


  • FoxDev

    @blakeyrat said:

    Still lacks Maximize/Minimize/whatever window widgets you have in your particular Linux OS, though

    It may not be minimisable/maximisable. Which is itself a WTF.



  • @RaceProUK said:

    It may not be minimisable/maximisable. Which is itself a WTF.

    Windows have two states: either they CAN be resized, or they CANNOT. If they CAN they need to have a Maximize widget. We have photographic evidence that the window can be resized, so the widget is undisputeably missing and wrong.

    They either CAN be minimized, or they CANNOT. If they CAN, they need to have a Minimize widget. (And really, there's no reason to make a window non-minimize-able.)


    To get back to the real point here, though: we're looking at a windowing framework written by a person/company that has no clue what an extremely simple window layout should even look like.



  • @Jaime said:

    You want to entirely change the architecture of an application so that you don't have to invest the one-time effort to figure out auto-update? I assure you it's easier than you think, even if you roll your own solution.

    My assumption is that if you have a running application, it is easier to update the application while it continues to run by downloading data than it is by downloading code. If you have evidence that contradicts this I would be interested to see it.

    @Jaime said:

    As for saving a compile - do you really think that 5 seconds will make a difference?

    I did say "might", but if you've only ever experienced 5 second compiles, then I need to know what line of business you're in. I think 2 minutes is the quickest turnaround I've seen in 15 years (and that was at the start of a project, and didn't last). I've worked on "hit F7, go make a cup of coffee or two" types of projects...


  • BINNED

    @RaceProUK said:

    It may not be minimisable/maximisable. Which is itself a WTF.

    It, in fact, is not. Double clicking the titlebar does nothing, neither does dragging it to the top edge. Also, dragging it to other edges of the screen which should resize it to fill half the screen doesn't work either, meaning it's not giving the window manager proper hints. I can still resize it manually though. Confusion abound,

    In short, someone went out of their way to fuck up the installer, because I never had a Qt application I made myself do that, so it's not a deficiency of Qt itself. WTF indeed.



  • @Onyx said:

    How is it supposed to look on Win8?

    See above: http://what.thedailywtf.com/t/ui-programming-for-the-chronically-distracted/8153/33

    The title bar is a bit off, but other than that it seems similar enough to me...



  • @tar said:

    My assumption is that if you have a running application, it is easier to update the application while it continues to run by downloading data than it is by downloading code. If you have evidence that contradicts this I would be interested to see it.

    That's easy, but you need to restart the application for all practical purposes anyway. You need to redraw at least all the widgets, possibly the windows themselves, re-attach all the event handlers, etc. It's like those Linux people who are like, "we can update without rebooting!"-- yeah, but you have to log out every user, stop and restart every service, how is that different from rebooting, practically speaking?

    Also imagine the complexities of, say, redesigning a UI element the user was right in the middle of using. Reasonably complex UI elements, the kind you'd want this feature actually for, generally take a significant amount of time to interact with. (Imagine for example applying pipeline effects to a Vegas media source. That's a single UI element you could spend hours on!) Wow you'd have pissed-off users. The only way to guarantee you're changing it when the user isn't using/about to use it is to close the program. Hey look, full circle.

    You also need the ability to update non-GUI-layout code anyway. So given those two "anyways", I'd say it's not an idea worth pursuing.


  • Discourse touched me in a no-no place

    This topic has reminded me to fire up VS and start playing around with C# and (for now) WinForms.



  • @blakeyrat said:

    That's easy, but you need to restart the application for all practical purposes anyway.

    I'm kind of spitballing now, but if we're designing an application from the ground up, then if the application's state is persisted appropriately, then this question should boil down to: can we fully rebuild the UI and app state quickly enough that the user won't notice (so <750ms ideally)?

    @blakeyrat said:

    You also need the ability to update non-GUI-layout code anyway. So given those two "anyways", I'd say it's not an idea worth pursuing.

    OK, this might be time better spent looking into unloading/reloading DLL's during application runtime, as it's a more general solution to the problem...

    (You know, I think Xbox development with its hard distinction between 'Title Update' vs 'Content Update' has started to pervade my worldview...)


  • Java Dev

    @blakeyrat said:

    Still lacks Maximize/Minimize/whatever window sizing widgets you have in your particular Linux OS, though.

    Some window managers (Gnome 3 for example) have a default configuration without minimize/maximize buttons. You can maximize by double-clicking the title bar (works on windows too!). Not sure about the fast way to minimize with the mouse, but there is one.



  • @tar said:

    I'm kind of spitballing now, but if we're designing an application from the ground up, then if the application's state is persisted appropriately, then this question should boil down to: can we fully rebuild the UI and app state quickly enough that the user won't notice (so <750ms ideally)?

    The only point to rebuilding the UI is to change the UI, and you damn well bet the user's going to notice a sudden change of the UI no matter how long it takes. And it'll be weird and disconcerting to them.



  • IIRC, that's at least partly because it's not written in Qt.
    I believe it's NSIS under Windows.

    Installers are almost universally poor though. There's no great ones at all, only 'good enough' and 'utter crap'.


Log in to reply