1

Lets say I have this enum

 public enum LogType
     {
         None = 0,
         File = 1,
         Folder = 2
     }

I have this ComboBox in view

    <ComboBox Name="CustomLogLogType"  FontSize="10"
              MinHeight="20" Height="20" SelectedItem="{Binding LogType}">

Then a ViewModel like so

public class CustomLogRuleItemViewModel : ReactiveObject
{

    [Reactive]
    public LogType LogType { get; set; } = LogType.File;

    public List<LogType> LogTypes => Enum.GetValues(typeof(LogType)).Cast<LogType>().Where(_ => _ != LogType.None).ToList();
}

Then in code behind for the view

public partial class CustomLogRuleItemView : ReactiveUserControl<CustomLogRuleItemViewModel> 
{
    public CustomLogRuleItemView()
    {
        InitializeComponent();

        this.ViewModel = new CustomLogRuleItemViewModel();
        this.DataContext = this.ViewModel;

        //The below works
        //CustomLogLogType.ItemsSource = this.ViewModel.LogTypes;


        this.WhenActivated(
            disposables =>
            {

                //If I use below it will error with exception
                this.OneWayBind(this.ViewModel,
                        _ => _.LogTypes, _ => _.CustomLogLogType.ItemsSource)
                    .DisposeWith(disposables);
            });
    }
}

Basically if I bind with below it works

CustomLogLogType.ItemsSource = this.ViewModel.LogTypes;

But if i try to use ReactiveUI to do the binding as in below

            this.OneWayBind(this.ViewModel,
                    _ => _.LogTypes, _ => _.CustomLogLogType.ItemsSource)
                .DisposeWith(disposables);

I get an exception stating that LogType on ReactiveUI.IViewFor violates the constraint of type 'T'. Unsure why I would be getting something arguing about IViewFor as that just has to do with the ViewModel implementation for view.

JMIII
  • 320
  • 2
  • 16
  • Just give the viewmodel a public collection property, and bind it in the XAML. What are you gaining from Reactive, other than headaches? – 15ee8f99-57ff-4f92-890c-b56153 Jun 26 '19 at 18:16
  • Well that is already the case? I already have a publicly accessible collection in the above view model. Also in above example if i bind without using reactive it works. I could do same thing in xaml as if it works in code behind will work in xaml. I gain having all my bindings uniform and in one spot with reactiveui. Also type safety etc in the code behind. I like that. – JMIII Jun 26 '19 at 18:24
  • Assigning isn't binding, btw. You're "solving" imaginary problems by creating real ones, but it's your code. Good luck. – 15ee8f99-57ff-4f92-890c-b56153 Jun 26 '19 at 18:38
  • You are correct sorry. But yes if i actually Bind in the xaml it works as well. – JMIII Jun 26 '19 at 18:39
  • How about this solution? https://stackoverflow.com/questions/58743/databinding-an-enum-property-to-a-combobox-in-wpf – k1ll3r8e Jun 26 '19 at 22:48

1 Answers1

3

The issue is that ReactiveUI by default will set a ItemTemplate by resolving for IViewFor<TypeInItemsSource> which is meant to make it easier to split off your views. So the automatic view lookup gets turned off if you add a ItemTemplate, DisplayMemberPath or ItemTemplateSelector in these scenarios. See this code for the line of code that does it.

<ComboBox Name="CustomLogLogType"  FontSize="10"
                  MinHeight="20" Height="20">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding}" />
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>

I was able to get around it by adding my own ItemTemplate.

I think this is realistically a bug though so if you don't mind opening a bug at https://github.com/reactiveui/ReactiveUI/issues I will put a fix in the next couple days for it. I don't think for primitive types we should be adding a ItemTemplate, since realistically I don't see users realistically wanting this feature for primitive types.

Glenn Watson
  • 2,758
  • 1
  • 20
  • 30
  • thanks a ton! I’ll log it on github. Really appreciate you explaining and appreciate your time as well! I’m still new to the library and am wrapping my head around. – JMIII Jun 27 '19 at 01:52
  • I'm adding an `ItemTemplate` with `{Binding}` and overriding `ToString()` in the data object class but I can't get my `ComboBox` to populate. I'm using MaterialDesignInXAML - does the style from that ComboBox require something else to work with besides what I already have? – Taryn Aug 10 '19 at 01:33