简体   繁体   中英

ComboBox Binding on First Item in UWP C#

is there a way when I build an UWP app to select the first entry in a combobox in pure XAML? Normally I would set IsSynchronizedWithCurrentItem="True" , but in UWP I only get an error that it cannot be set.
The SelectedItem does not work, only if I set it explicitly to the same as the ItemsSource with an [0] after it, but then the second ComboBox does not update on changes and shows empty entries again. Here is my code:

<ComboBox x:Name="MainSystemComboBox" 
          ItemsSource="{Binding Path=EditRulesViewModel.RuleSet.RuleMainSystems}" 
          SelectedItem="{Binding Path=EditRulesViewModel.RuleSet.RuleMainSystems, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
          DisplayMemberPath="Name" SelectedValuePath="Id" />

<ComboBox x:Name="SubSystemComboBox" 
          ItemsSource="{Binding Path=SelectedItem.RuleSubSystems, ElementName=MainSystemComboBox}" 
          DisplayMemberPath="Name" SelectedValuePath="Id" />

Oh and it shows to me in the designer that the Path of the second ComboBox is incorrect, because it couldn't resolve property 'RuleSubSystems' in data context of type 'object', but after compiling it works well (except the selection of the first entry). Is there a cleaner way of binding one ComboBox to another?

Objects are simple

public class RuleMainSystem
{
    public string Name { get; set; }
    // Some more single properties...
    public ObservableCollection<RuleSubSystem> RuleSubSystems { get; set; }
}

and

public class RuleSubSystem
{
    public string Name { get; set; }
    // Some more single properties...
}

The SelectedItem does not work, only if I set it explicitly to the same as the ItemsSource with an [0] after it

You bind the ItemsSource and SelectedItem to the same one property RuleMainSystems , it's not correct. You would have to bind the SelectedItem to a specific item. Eg, RuleMainSystems[0]

but then the second ComboBox does not update on changes and shows empty entries again.

That's because you have not bound SelectedItem , you need to do like the following:

<ComboBox x:Name="SubSystemComboBox" 
      ItemsSource="{Binding Path=SelectedItem.RuleSubSystems, ElementName=MainSystemComboBox}" SelectedItem="{Binding Path=SelectedItem.RuleSubSystems[0], ElementName=MainSystemComboBox}"
      DisplayMemberPath="Name" SelectedValuePath="Id" />

Updated on [2018/5/28]

<ComboBox x:Name="MainSystemComboBox" 
      ItemsSource="{Binding Path=RuleMainSystems}" 
      SelectedItem="{Binding Path=MySelectedItem, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
      DisplayMemberPath="Name" SelectedValuePath="Id"/>

<ComboBox x:Name="SubSystemComboBox" 
      ItemsSource="{Binding RuleSubSystems}" SelectedItem="{Binding SubSelectedItem,Mode=TwoWay}"
      DisplayMemberPath="Name" SelectedValuePath="Id" />
public class RuleMainSystem
{
    public string Name { get; set; }
    // Some more single properties...
    public ObservableCollection<RuleSubSystem> RuleSubSystems { get; set; }
}

public class RuleSubSystem
{
    public string Name { get; set; }
    // Some more single properties...
}
public MainPage()
{
    this.InitializeComponent();
    this.DataContext = new EditRulesViewModel();
}
public class EditRulesViewModel:ViewModelBase
{

    public ObservableCollection<RuleMainSystem> RuleMainSystems { get; set; }

    private RuleMainSystem _MySelectedItem;
    public RuleMainSystem MySelectedItem
    {
        get { return _MySelectedItem; }
        set
        {
            _MySelectedItem = value;
            RuleSubSystems = MySelectedItem.RuleSubSystems;
            SubSelectedItem = MySelectedItem.RuleSubSystems.FirstOrDefault();
            RaisePropertyChanged("MySelectedItem");
        }
    }


    private ObservableCollection<RuleSubSystem> _RuleSubSystems;
    public ObservableCollection<RuleSubSystem> RuleSubSystems
    {
        get { return _RuleSubSystems; }
        set
        {
            _RuleSubSystems = value;
            RaisePropertyChanged("RuleSubSystems");
        }
    }


    private RuleSubSystem _SubSelectedItem;
    public RuleSubSystem SubSelectedItem
    {
        get { return _SubSelectedItem; }
        set
        {
            _SubSelectedItem = value;
            RaisePropertyChanged("SubSelectedItem");
        }
    }


    public EditRulesViewModel()
    {
        RuleMainSystems = new ObservableCollection<RuleMainSystem>();

        ObservableCollection<RuleSubSystem> SubSystems = new ObservableCollection<RuleSubSystem>();
        SubSystems.Add(new RuleSubSystem() {Name="Sub1" });
        SubSystems.Add(new RuleSubSystem() {Name="Sub2" });

        ObservableCollection<RuleSubSystem> SubSystems1 = new ObservableCollection<RuleSubSystem>();
        SubSystems1.Add(new RuleSubSystem() { Name = "Sub3" });
        SubSystems1.Add(new RuleSubSystem() { Name = "Sub4" });

        RuleMainSystems.Add(new RuleMainSystem() {Name="Rule1",RuleSubSystems = SubSystems });
        RuleMainSystems.Add(new RuleMainSystem() { Name = "Rule2", RuleSubSystems = SubSystems1 });
        MySelectedItem = RuleMainSystems.FirstOrDefault();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM