How to Bind an Enum to a ComboBox in WPF

Поделиться
HTML-код
  • Опубликовано: 10 сен 2024
  • In this video, I answer the question "How to Bind an Enum to a ComboBox in WPF?".
    When most WPF developers bind an enum to a combobox in WPF, they use the standard ObjectDataProvider approach. This consists of creating an ObjectDataProvider as a resource in tour wpf application. Setting the MethodName and ObjectType properties. Then you have to provide the ObjectDtaProvider MethodParameters which is the type of the enum you want to bind. Finally, you can then bind your ComboBox ItemsSource property to the ObjectDataProvider resources, which will essentially bind your enum to the combobox.
    That's a lot of code, and it sucks really bad. After seeing the "official" (crappy) WPF approch to bind an enum to a ComboBox using an ObjectDataProvider, I will show you my approach.
    My approach takes advantage of a custom MarkupExtension that can be used to bind an enum to a ComboBox just by setting the binding on the ItemsSource property. No need for an ObjectDataprovider.
    You'll soon see why my way is the better approach to bind an enum to a combobox in WPF.
    Be sure to watch my new Pluralsight course "Introduction to Prism for WPF":
    pluralsight.px...
    Sponsor Me:
    github.com/spo...
    Follow Me:
    Twitter: / brianlagunas
    Twitch: / brianlagunas
    Blog: brianlagunas.com
    GitHub: github.com/bri...

Комментарии • 119

  • @BrianLagunas
    @BrianLagunas  4 года назад +18

    Well crap... I just realized I updated the ItemsSource property wrong in the video! You can simple use
    ItemsSource="{local:EnumBindingSource local:Status}"
    Sorry about that 😁

    • @JacobEgner
      @JacobEgner 4 года назад +1

      In Xamarin.Forms, it's possible you still need the {x:Type local:Status}. I just tried Dan Siegel's Xamarin.Forms snippet and got build time error from XamlC if I removed x:Type. Maybe the error would go away if I didn't do compiled bindings, but I love compiled bindings too much to disable them.

    • @BrianLagunas
      @BrianLagunas  4 года назад

      @@JacobEgnerGod to know, thanks for sharing. If only they would use a common XAML markup 😂

    • @JacobEgner
      @JacobEgner 4 года назад

      @@BrianLagunas Yeah, in the last Xamarin survey I took, my biggest feedback was "avoidable xaml differences between Xamarin and WPF are bad".

  • @NickBullCSharp
    @NickBullCSharp 4 года назад +4

    Oh wow. This approach is fantastic!! Really this is so much better. Thank you for sharing 😁😁

    • @BrianLagunas
      @BrianLagunas  4 года назад +1

      Thank you so much, Be sure to read the pinned comment as I made a slight mistake in my recording. It's even easier 😁

    • @NickBullCSharp
      @NickBullCSharp 4 года назад

      I'm guessing then to bind to the SelectedItem You would just do SelectedItem="{Binding SelectedObj}"? You wouldn't need any converter or extra bloated code?

    • @BrianLagunas
      @BrianLagunas  4 года назад +1

      @@NickBullCSharp Correct. No converters needed. The selected value will be of the EnumType.

    • @NickBullCSharp
      @NickBullCSharp 4 года назад +1

      @@BrianLagunas Oh my days, you are fantastic. This will clean up my code big time 😜. I've had to write converters in the past lol

  • @termuxparadev
    @termuxparadev 3 года назад +1

    Brian Lagunas, congratulations on the video and knowledge. I was very happy to know your channel and especially the easy and professional way you program. Greetings from The Brazil.

    • @BrianLagunas
      @BrianLagunas  3 года назад +1

      I appreciate that! Thank you for watching

  • @nandkishorsonwale
    @nandkishorsonwale 4 года назад +1

    Brian approach is really fantastic. Thanks for great video.

  • @AanDahliansyah
    @AanDahliansyah 4 года назад +2

    Hi Brian, all your video material is good.

  • @kasozivincent107
    @kasozivincent107 4 года назад +1

    Thanks for the video Brian. I find them useful always.

  • @joyios8830
    @joyios8830 Год назад +1

    very good sir!!!

  • @solvedplus858
    @solvedplus858 3 года назад +1

    great , many thanks

  • @martinlanza1236
    @martinlanza1236 11 месяцев назад +1

    Nice implementation - appreciated

  • @essamsalah829
    @essamsalah829 3 года назад +2

    hi Brian
    but what if we want to bind to the same Enum after adding this Type Attribute to get the enum not the enum description??
    thanks in advance.

    • @BrianLagunas
      @BrianLagunas  3 года назад +1

      Well, you would probably have to create another binding extension that removes the typeconverter or the description attributes before you get the values. Or, you could possibly use a converter instead.

  • @JacobEgner
    @JacobEgner 4 года назад +3

    Oh, Brian, you always delight and never disappoint. This is good stuff and I look forward to using it. I'm guessing it would work in Xamarin.Forms too?

    • @BrianLagunas
      @BrianLagunas  4 года назад +1

      Yeah, I don't see why it wouldn't work in XF. I'd have to try to be 100% sure.

    • @JacobEgner
      @JacobEgner 4 года назад +2

      @@BrianLagunas For the sake of other readers, there was another place where Dan Siegel confirmed Brian's answer.

    • @JacobEgner
      @JacobEgner 4 года назад +1

      Also Dan Siegel posted a gist for Xamarin: twitter.com/DanJSiegel/status/1295797588977807360

  • @mgregory22
    @mgregory22 4 года назад +1

    Thanks! That's incredibly cool. I didn't know about ObjectDataProvider, or how easy it is to make my own markup extension.

  • @lukaszluczko
    @lukaszluczko 3 года назад +1

    Hi Brian, I have Combobox1 and Combobox2.
    Combobox1 is binded to enum1 {ac, df, gj}.
    Combobox2 is binded to enum2 {a, b, c, d, e, f, g, h, i, j}.
    If I choose on Combobox1 value 'ac' then I want to filter options on Combobox2 to only {a, b, c}.
    Do You know solutions for that?

    • @BrianLagunas
      @BrianLagunas  3 года назад +1

      My first thought is to use a converter

  • @lionelpeeters4466
    @lionelpeeters4466 2 года назад

    How do we use the EnumBindingSourceExtension when we are creating the combobox from C# instead of xaml?

  • @DoctorMGL
    @DoctorMGL 2 года назад

    can the same thing be done with ObservableCollections< person > ?

  • @PauloMorgado
    @PauloMorgado 4 года назад +1

    A private setter allows a property to be set anywhere within the class or any of its inner types.
    A read-only auto property has no declared setter and can be set in the constructor but not outside the constructor..

    • @BrianLagunas
      @BrianLagunas  4 года назад

      Exactly! Thanks for clarifying. I should have used a ReadOnly property in this case, but when I am recording I don't think about everything 😂

  • @taruntirkey
    @taruntirkey 4 года назад +2

    You never stop to amaze me. Thanks for such informative videos. Long back I had watched your Prism tutorial course in pluralsight and have been following your blogs since then.
    Will it work if I use a wrap panel to give a layout like in windows 10 settings. And also I would like add or remove modules without making any changes in code.
    Just wanted an expert advice before starting on a personal project. Thanks in advance. 🙂

    • @BrianLagunas
      @BrianLagunas  4 года назад

      Thank you for watching. I'm not sure I understand your question completely. When it comes to layout, you can do anything in WPF. You can easily add modules at anytime with Prism. Removing modules is not a thing, but perhaps you are just wanting to remove views, which is easily done.

  • @piotrgoacki9070
    @piotrgoacki9070 2 года назад

    I don't understand how it is bound to a ViewModel. I would like to use use two-way binding. If I have a property in my ViewModel of enum type how I can bind to this property using this approach? Do I need a separate event handler or something to make it work?

    • @piotrgoacki9070
      @piotrgoacki9070 2 года назад

      It turns out that you just need to bind to SelectedItem property to a property in your view model. Another of this cases where I could say "it works, but I don't know why" :)

    • @BrianLagunas
      @BrianLagunas  2 года назад

      The power of data binding 😁

  • @Tamer_Ali
    @Tamer_Ali 4 года назад

    Hey Brian,
    Is there is away to change the direction (RTL/LTR) of the form/control after changing the culture in WPF or Xamarin Forms using prism?
    Thanks

    • @BrianLagunas
      @BrianLagunas  4 года назад

      In WPF you use a combination of the xml:lang attribute for hyphenation, spell checking, number substitution, and font fall back. You also would set the FlowDirection property on every page. You'll also need to use the x:Uid attribute. There's actually a lot that goes into localizing an application 😁

  • @kingofthuglifejethalal1417
    @kingofthuglifejethalal1417 2 года назад

    can I create this enum in mainwindow class and access it in object data provider?
    if yes then please tell me how I googled it a lot but didnt find any answer.

    • @BrianLagunas
      @BrianLagunas  2 года назад

      Don't use nested types (such as nesting an enumeration within a class) when you define your code for use with XAML. Nested types can't be evaluated. There's no way for the XAML parser to distinguish that a dot is part of the nested type name rather than part of the namespace name. If you really want to do this, then you'd need to create a custom markup extension to parse the nested class to return the type properly.

  • @AntonioGomez-qh2fe
    @AntonioGomez-qh2fe 3 года назад

    I implemented the technique you described under the .NET Framework 4.8. However when I migrated to .NET 5 access to the implementation of MarkupExtension was compromised. There is no nuget package available for the assembly and manually referencing it gets me a compile error. Could you give me some advice? Thanks

    • @BrianLagunas
      @BrianLagunas  3 года назад

      Try deleting your obj and bin folders and do a rebuild.

    • @AntonioGomez-qh2fe
      @AntonioGomez-qh2fe 3 года назад

      @@BrianLagunas Thanks for the suggestion, Brian. It did not work as expected, however. I decided to search nuget for an assembly that contained all or part of System.Xaml instead. I found the Avalonia.Markup.XamlLoader (0.10.6) and it seemed to have solved the problem. I was naively under impression that migration to the .NET 5 platform would not incur breaking changes caused by someone deciding for me what core (System.Xaml is older than I am...) for me. Thanks for your great idea and thanks for your help.

    • @BrianLagunas
      @BrianLagunas  3 года назад

      Did you convert the DNF app to .NET 5 or did you start with a new .NET 5 app? I feel you may have made a mistake if you did a manual conversion. I just tested and it works fine with no added dependencies

    • @AntonioGomez-qh2fe
      @AntonioGomez-qh2fe 3 года назад

      @@BrianLagunas I used the migration tool. I am not surprised you think I may have made a mistake. It has been a real uphill battle.

  • @Tamer_Ali
    @Tamer_Ali 4 года назад +1

    Amazing video

  • @samitskovich6137
    @samitskovich6137 4 года назад +2

    Hey Brian, Thanks for doing this series! This is a gold mine! Could you do a video on configuring core services like logging and configuration management in a Prism application?

    • @BrianLagunas
      @BrianLagunas  4 года назад

      Can you provide a little more detail on what you mean by configuration management?

    • @samitskovich6137
      @samitskovich6137 4 года назад

      Sure, what I was referring to was setting up a prism app to pull configuration data from an appsettings.json file or environment settings, for say adding modules or connection strings, while, at the same time leveraging Prisms IOC mechanisms. I guess what isn’t clear to me is which configuration components from Microsoft (host builder) duplicate some of the IOC mechanisms that prism provides and how to navigate the overlap.
      Thanks!

    • @BrianLagunas
      @BrianLagunas  4 года назад

      Modules can only be added via app.config, xaml file, directory, or code out of the box. You'd need to write a custom module catalog to support JSON. Your other actions should be in a service you register with the container. Prism doesn't support the MS DI container as its missing too many features.

  • @sergiotardo
    @sergiotardo 4 года назад +1

    amazing Solution thanks!!!!!

  • @hossammoussa2333
    @hossammoussa2333 2 года назад +1

    Clean coding

  • @user-ry2ob3sj3z
    @user-ry2ob3sj3z 2 года назад +1

    👍👍

  • @abhinovpankaj1
    @abhinovpankaj1 3 года назад

    Was trying to implement same in UWP, but it didn't work. How to implement in UWP?

    • @BrianLagunas
      @BrianLagunas  3 года назад

      What didn't work? What did you try?

  • @JoeBonez
    @JoeBonez 4 года назад +1

    I like this solution. Very clean. I’ve always used an ObservableCollection populated in the constructor of my ViewModel, and bound the SelectedValue property to a Foo property in the VM. Question: how are you accessing the selected value in a view model, or are you doing it in code behind?

    • @BrianLagunas
      @BrianLagunas  4 года назад +1

      Now you don't need to polite your VM with another property. Just data bind the SelectedItem to a property in my VM.

    • @JoeBonez
      @JoeBonez 4 года назад +1

      Brian Lagunas of course! Get rid of the ObservableCollection, but keep the SelectedValue bind. So clean. Thanks!

  • @kunjalshah5123
    @kunjalshah5123 4 года назад +1

    Great video! Sound is synced properly also.
    I had a question on injecting dependencies into a singleton class using Prism.
    I have the following class:
    public class Foo : IFoo
    {
    private static Foo instance;
    private Foo() {}
    public static Foo Instance => instance ?? (instance = new Foo())
    }
    I've registered this with the IoC container as follows:
    containerRegistry.RegisterInstance(Foo.Instance);
    I now want to inject the IEventAggregator into this class. How would I do that?

    • @BrianLagunas
      @BrianLagunas  4 года назад

      That static is not needed. Just register it as a Singleton. Avoid statics like that.
      containerRegistry.RegisterSingleton();
      public class Foo : IFoo
      {
      public Foo(IEvevntAggregator ea) {..}
      }

  • @ooikaiyang9254
    @ooikaiyang9254 3 года назад

    Hello Brian, If there are some data in Enum that want to ignore. it's any way to do it ?
    Example: there have 4 data in Enum [a, b, c , d] just want to bind [a, b, c] to the combo box.

    • @BrianLagunas
      @BrianLagunas  3 года назад +1

      Of course. The best way would be to add a property to the EnumBindingSourceExtension called Exclude and make it a List(string). Then use that list to filter out the values you don't want to appear in the ProvideValue method. Something like.... if (!Exclude.Contains(Enum.GetName(EnumType, item))) result.Add(item);

    • @ooikaiyang9254
      @ooikaiyang9254 3 года назад +1

      @@BrianLagunas Awww.. Thanks Brian

  • @terjes64
    @terjes64 Год назад

    Is it possible to use a valueconverter here? (sorry wpf noob)

  • @neralem
    @neralem 3 года назад

    Mh yeah nice...but...how often do you display the values of the enum inside the ui like they are called in the code? I'm interested in a way to create a mapping of enum values and strings only inside xaml and use this for databinding in my MVVM application. Do you know a way to accomplish this without defining a dictionary in the Viewmodel?

    • @BrianLagunas
      @BrianLagunas  3 года назад

      Yes, watch this video ruclips.net/video/T1mhORJCDsY/видео.html

  • @mywildlifestories3793
    @mywildlifestories3793 4 года назад

    Hi Brian, is there a way to make Scrollviewer invisible in wpf?. I mean Scrollviewer should be there but should not be visible to the user?

    • @BrianLagunas
      @BrianLagunas  4 года назад

      I think you are talking about showing and hiding the ScrollViewer scrollbars? If so then yes, you can control this on any element that contains a scroll viewer by using the ScrollViewer.HorizontalScrollBarVisibility and ScrollViewer.VerticalScrollBarVisibility attached properties.

    • @mywildlifestories3793
      @mywildlifestories3793 4 года назад

      @@BrianLagunas in our case user should still able to scroll, but the scroll viewer should not be visible to the user

  • @harsheng
    @harsheng 4 года назад +1

    What is the best of binding svg image in wpf?

  • @inusbotha6859
    @inusbotha6859 4 года назад +1

    Great content Brian! Short and to the point. Any possibility of doing a vid on writing proper unit tests?

    • @BrianLagunas
      @BrianLagunas  4 года назад

      Sure. I can do a unit test video. I don't know if it'll be "proper", but it will test things 🤣. Anything specific you're trying to test?

    • @inusbotha6859
      @inusbotha6859 4 года назад

      @@BrianLagunas great! Perhaps a general video focusing on test driven development

    • @BrianLagunas
      @BrianLagunas  4 года назад

      I don't belive in TDD in general. TDD is different than just unit testing.

  • @glaysonpatricio
    @glaysonpatricio 3 года назад

    Thankyou very much for the video. However I would like to ask if you know a simple solution like that if we wish to convert an enum with underline in space. ex : "Days_Of_Week" >> "Days Of Week"

    • @BrianLagunas
      @BrianLagunas  3 года назад +1

      You would just have to modify the type converter to replace your underscores with spaces

  • @tomroberts1216
    @tomroberts1216 3 года назад

    Thanks Brian. This approach is great. The ItemSource property naming convention is a little mysterious. It seems it would be more intuitive that the convention would be ItemSource="{local:EnumBindingSourceExtension local:Status}" to match the name of the extension class instead of ItemsSource="{local:EnumBindingSource local:Status}" or is Extension just redundant and left out of the binding?

    • @tomroberts1216
      @tomroberts1216 3 года назад

      I just tried ItemSource="{local:EnumBindingSourceExtension local:Status}" and that works too!

    • @BrianLagunas
      @BrianLagunas  3 года назад

      @@tomroberts1216 Yes, this is a naming convention enforced by WPF. You can choose to add the "Extension" to the class name in the extension use, or leave it out. As you can see, either will work.

  • @sneffetsd
    @sneffetsd 2 года назад

    And how I bind that value to an object?

    • @sneffetsd
      @sneffetsd 2 года назад

      Got it working
      SelectedItem="{Binding classpath}"

  • @midizengm
    @midizengm 3 года назад

    Does it fit for DataGrid Combobox?

  • @saifurrehman0
    @saifurrehman0 4 года назад +1

    Still doing WPF? I shifted to angular and love angular material UI components. Microsoft will never provide mature UI components like angular material for WPF or Blazor.

    • @BrianLagunas
      @BrianLagunas  4 года назад +1

      I do a little bit of everything. I am always jumping between platforms. The main platforms I work with today are WPF, Angular, Blazer, Vue, React, and Xamarin.Forms. Soon to add Uno to that list.

  • @Kerbargos
    @Kerbargos 4 года назад +1

    Hello Brain firstly thank you for your sharing. If you could please start a blazor course on youtube. It should be very useful. Thank you in advance.

    • @BrianLagunas
      @BrianLagunas  4 года назад

      Noted. Courses take a crap ton of time to plan and create, but I'll add it to my todo list.

    • @Kerbargos
      @Kerbargos 4 года назад +1

      @@BrianLagunas thank you Brain. Your teaching tecnique is very clear. I like to learn from your vidoes. Good job.

  • @julianturner6203
    @julianturner6203 4 года назад

    Thanks for the video. Why can't just use an converter for this?

    • @BrianLagunas
      @BrianLagunas  4 года назад +1

      You can use a converter, but this actually requires much more code, and is way more limiting. For example; you'll need to expose a collection on your VM that represents your Enum to data bind to, then create a converter with your converter logic, which must be defined as a resource in xaml and then added to the binding. Localization becomes more of a challenge as well.

    • @julianturner6203
      @julianturner6203 4 года назад

      @@BrianLagunas thank you for your time Brian

  • @ooikaiyang9254
    @ooikaiyang9254 4 года назад

    What if the Status class have multiple class of Enum ??

    • @BrianLagunas
      @BrianLagunas  4 года назад

      I'm sorry, I do not understand. Status is not a class but an enum. Could you try to explain differently?

    • @ooikaiyang9254
      @ooikaiyang9254 4 года назад

      @@BrianLagunasSorry for poor explaination. it's mean Status.cs inside have multiple of Enum, when binding the item source is just following the Enum name instead of Status ?

    • @BrianLagunas
      @BrianLagunas  4 года назад +1

      Yes, you would provide the type of the enum, not the name of the .cs file.

    • @ooikaiyang9254
      @ooikaiyang9254 4 года назад +1

      @@BrianLagunas Thanks Brian. Learn a lot from your video.

  • @davidwhite2011
    @davidwhite2011 4 года назад

    I take it there is no way to do this with multi language support? Mic sounds much better by the way.

    • @BrianLagunas
      @BrianLagunas  4 года назад

      The only way would be with language subtitles, bu I can't afford that 😁. Thanks for the mic feedback. I'll stick to this mic from now on.

    • @davidwhite2011
      @davidwhite2011 4 года назад

      @@BrianLagunas I mean in a wpf program, multi language support using this way to bind.

    • @BrianLagunas
      @BrianLagunas  4 года назад

      @@davidwhite2011 Ahhh.. So you want to be able to localize the enum in the combo box? So if I am in Japanese the enum values will be displayed in Japanese in the comboBox, but the underlying value will still be the enum type?