0

I have a combobox which is bound to a property called "BlockDetails" in the viewmodel. When I expand the combobox I can see the items inside it. But the problem is it doesn't select/display the item. On top when I set SelectedValue="{Binding BlockName,Mode=TwoWay}", in the output window it gives a binding path error saying 'Error: BindingExpression path error: 'BlockName' property not found on 'Presentation.InstrumentUI.ViewsLoggedIn.ServiceUtilityMethodsView'. BindingExpression: Path='BlockName' DataItem='Presentation.InstrumentUI.ViewsLoggedIn.ServiceUtilityMethodsView'; target element is 'Windows.UI.Xaml.Controls.ComboBox' (Name='null'); target property is 'SelectedValue' (type 'Object')'. I don't understand why is it going and searcing in the View instead of the model. Please help.

Here is my combobox

<ComboBox uwpControls:DockPanel.Dock="Right"
                              Margin="16,0,0,0"
                              Style="{StaticResource ComboBoxStyleForm}"
                              ItemsSource="{x:Bind ViewModel.BlockDetails,Mode=TwoWay}"
                              DisplayMemberPath="BlockName"
                              SelectedValuePath="BlockName"
                              SelectedValue="{Binding BlockName,Mode=TwoWay}"></ComboBox>

In the code behind I have the ViewModel as follows, the item source for the Combobox is bound correctly

 public IServiceUtilityMethodsViewModel ViewModel { get; }
        public ServiceUtilityMethodsView()
        {
            InitializeComponent();
            ViewModel = LifetimeScope.Resolve<IServiceUtilityMethodsViewModel>();
            DataContext = this;
        }

Here is the viewmodel property.

 public List<VmServiceMethodBlockDefinition> BlockDetails
        {
            get => _blockDetails;
            set => Set(ref _blockDetails, value);
        }

In my model the class is declared as follows,

public class VmServiceMethodBlockDefinition : BindableBaseThreadSafe
    {
        private string _blockName;
        public string BlockName
        {
            get => _blockName;
            set => Set(ref _blockName, value);
        }

        private List<VmServiceMethodBlockParameters> _blockParameters;
        public List<VmServiceMethodBlockParameters> BlockParameters
        {
            get => _blockParameters;
            set => Set(ref _blockParameters, value);
        }
    }
Clemens
  • 123,504
  • 12
  • 155
  • 268
nikhil
  • 1,578
  • 3
  • 23
  • 52
  • 1
    It's telling you it has no blockname property in it's datacontext that would be set from the selectedvalue. From your code, i see a vm has blockname but can't be the vm because it has blockparameters rather than blockdetails – Andy Oct 21 '20 at 18:05
  • The property `BlockName` is declared in the type `VmServiceMethodBlockDefinition`, but from the error message your data context is `ServiceUtilityMethodsView`, which is a consequence of `DataContext = this;` in that type's constructor. There's not enough detail in the question to explain what the right way to fix the problem is, but it's pretty obvious how your code is wrong. – Peter Duniho Oct 21 '20 at 18:10
  • Hi. Note that your binding `x:Bind` which binds to the `BlockDetails` collection should be `OneTime` (which is the default): `ItemsSource="{x:Bind ViewModel.BlockDetails}"`. This significantly improves performance. Since you are not using a `ObservableCollection`, I assume that the source collection won't change. – BionicCode Oct 21 '20 at 19:31
  • 1
    When you follow my suggested answer, you can leave your `DataContext` set to `this`. Just keep in mind that you have to use `x:Bind` to reference the `IServiceUtilityMethodsViewModel`. `Binding` will always target the current scope's `DataContext`. – BionicCode Oct 21 '20 at 19:34

1 Answers1

0

I think you either confused the SelectedValue property or missed to post some details.
You have an object or data type that is an item of the ComboBox.
You have ComboBox.DisplayMemberPath to select the property of this data type, which should be displayed by the ComboBox in the drop down.
Finally you have ComboBox.SelectedValuePath to select a property of this data type to be the ComboBox.SelectedValue. You use ComboBox.SelectedValue instead of ComboBox.SelectedItem, if you are not interested of the actual data item, but a specific value of this item. Both properties serve the same purpose of exposing the currently selected item.

You typically bind this ComboBox.SelectedValue to the same view model (data context) that exposes the source collection, in your case the BlockDetails collection. Your view model should have a property SelectedBlockName. Then use x:Bind to bind the ComboBox.SelectedValue to this property:

IServiceUtilityMethodsViewModel

public List<VmServiceMethodBlockDefinition> BlockDetails
{
  get => _blockDetails;
  set => Set(ref _blockDetails, value);
}

private string _selectedBlockName
public string SelectedBlockName
{
  get => _selectedBlockName;
  set => Set(ref _selectedBlockName, value);
}

XAML

<ComboBox ItemsSource="{x:Bind ViewModel.BlockDetails, Mode=OneTime}"
          DisplayMemberPath="BlockName"
          SelectedValuePath="BlockName"
          SelectedValue="{x:Bind ViewModel.SelectedBlockName, Mode=TwoWay}" />
BionicCode
  • 1
  • 4
  • 28
  • 44
  • Can you help me with this post https://stackoverflow.com/questions/64560391/accesing-the-tag-element-from-content-control-and-access-it-inside-the-data-temp – nikhil Oct 27 '20 at 18:05