【问题标题】:Select one combo box value on the basis of another combo box value在另一个组合框值的基础上选择一个组合框值
【发布时间】:2017-04-19 23:56:50
【问题描述】:

我是 WPF 应用程序开发的新手。我想在块的基础上获得楼层。我有一个积木组合框和另一个地板组合框。当我在一个组合框中选择任何块时,另一个组合框应显示选择块的楼层。 这是组合框布局:

<ComboBox Grid.Row="0" Grid.Column="0" Width="100"
          Margin="0,0,0,10" Height="35"
          Loaded="FrameworkElement_OnLoaded"
          SelectedValuePath ="Id"
          SelectedValue ="{Binding SelectedBlockId, Mode=TwoWay}"
          DisplayMemberPath="Name"
          SelectionChanged="Selector_OnSelectionChanged" ItemsSource="{Binding Blocks}"  />

<ComboBox Grid.Row="0" Grid.Column="3" Width="100"
          Margin="0,0,0,10" Height="35"
          Loaded="FrameworkElement_OnLoaded"
          SelectedValuePath ="Id"
          SelectedValue ="{Binding SelectedFloorId, Mode=TwoWay}"
          DisplayMemberPath="Name"
          SelectionChanged="Selector_OnSelectionChanged" ItemsSource="{Binding Floors}"  />

【问题讨论】:

  • 好像你的问题缺少一些代码......比如Selector_OnSelectionChanged()
  • private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs e) { }

标签: wpf mvvm prism


【解决方案1】:

有关如何使用 MVVM 模式在 WPF 中实现级联 ComboBox 的示例,请参阅以下博客文章:https://blog.magnusmontin.net/2013/06/17/cascading-comboboxes-in-wpf-using-mvvm/

您基本上可以将示例代码中的 Country 和 Cities 类型替换为 Block 和 Floor 类型。

【讨论】:

  • 欢迎来到 Stack Overflow!这是一个边界link-only answer。您应该在此处扩展您的答案以包含尽可能多的信息,并使用该链接仅供参考。
【解决方案2】:

您需要做的是在BlockFloor 模型之间建立主从关系,并将它们正确绑定到您的视图(组合框)。

假设您的FloorBlock 有两个属性IDDescription,您的模型应该如下所示:

public class Floor
{
    public int Id { get; set; }
    public string Description { get; set; }
}

public class Block
{
    public int Id { get; set; }
    public int Description { get; set; }
    // notice Floors collection inside each block
    public IList<Floor> Floors { get; set; }

    public Block()
    {
        Floors = new List<Floor>();
    }
}

您的 ViewModel 将包含两个 ObservableCollections 和一个用于存储当前选定块的属性。注意SelectedBlock 属性设置器:当属性更新时,Floors 集合会使用新值重新创建。

public const string BlocksPropertyName = "Blocks";
private ObservableCollection<Block> _blocks = null;
public ObservableCollection<Block> Blocks
{
    get
    {
        return _blocks;
    }
    set
    { 
        _blocks = value;
        RaisePropertyChanged(BlocksPropertyName);
    }
}

public const string SelectedBlockPropertyName = "SelectedBlock";
private Block _selectedBlock = null;
public Block SelectedBlock
{
    get
    {
        return _selectedBlock;
    }
    set
    {
        _selectedBlock = value;
        RaisePropertyChanged(SelectedBlockPropertyName);

        if (_selectedBlock != null)
        {
            Floors = new ObservableCollection<Floor>(_selectedBlock.Floors);
        }
    }
}

public const string FloorsPropertyName = "Floors";
private ObservableCollection<Floor> _floors = null;
public ObservableCollection<Floor> Floors
{
    get
    {
        return _floors;
    }
    set
    {
        _floors = value;
        RaisePropertyChanged(FloorsPropertyName);
    }
}

在您的 XAML 中,您只需将两个 ComboBox 绑定到相关集合:

<ComboBox ItemsSource="{Binding Blocks}"
          SelectedItem="{Binding SelectedBlock}" />

<ComboBox ItemsSource="{Binding Floors}" />

【讨论】:

    【解决方案3】:

    这里有一个稍微不同的例子。

    Xaml...

    <!-- language: xaml -->
    <Label Name="FavoriteFoodLbl" Grid.Column="0" Grid.Row="13">Favorite Food</Label>
    <ComboBox Name="FavoriteFoodCombo" Grid.Column="1" Grid.Row="13" ItemsSource="{Binding Foods}" SelectedItem="{Binding FavoriteFood, UpdateSourceTrigger=PropertyChanged}" />
    
    <Label Name="FavoriteFlavourLbl" Grid.Column="2" Grid.Row="13">Favorite Flavour</Label>
    <ComboBox Name="FavoriteFlavourCombo" Grid.Column="3" Grid.Row="13" ItemsSource="{Binding Flavours}"  />
    

    查看模型/代码隐藏代码...

        public event PropertyChangedEventHandler PropertyChanged;
    
        public ObservableCollection<string> Foods { get; set; } = new ObservableCollection<string>() { "Pizza", "Ice Cream", "Soup" };
    
        private string _favoriteFood;
        public string FavoriteFood
        {
            get { return _favoriteFood; }
            set
            {
                _favoriteFood = value;
                switch (_favoriteFood)
                {
                    case "Pizza":
                        _flavours = new ObservableCollection<string>(PizzaToppings);
                        break;
                    case "Ice Cream":
                        _flavours = new ObservableCollection<string>(IceCreamFlavours);
                        break;
                    case "Soup":
                        _flavours = new ObservableCollection<string>(SoupFlavours);
                        break;
                    default:
                        _flavours = new ObservableCollection<string>();
                        break;
                }
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("FavoriteFood"));
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Flavours"));
            }
        }
    
        public List<string> PizzaToppings { get; set; } = new List<string>() { "Margarita", "Pepperoni", "Meat Feast" };
        public List<string> IceCreamFlavours { get; set; } = new List<string>() { "Vanilla", "Strawberry", "Chocolate" };
        public List<string> SoupFlavours { get; set; } = new List<string>() { "Tomato", "Leek and Potato", "Chicken" };
    
        private ObservableCollection<string> _flavours = null;
        public ObservableCollection<string> Flavours
        {
            get
            {
                return _flavours;
            }
            set
            {
                _flavours = value;
                RaisePropertyChanged();
            }
        }
        public string FavoriteFlavour { get; set; }
    

    将 case 语句更改为适当的内容。 这有帮助吗?

    【讨论】:

    • 我在使用MVVM,请根据MVVM架构回答我
    • 该代码应该在您的视图模型中工作。不是吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-07
    • 2014-11-22
    • 1970-01-01
    • 2012-02-29
    • 1970-01-01
    • 2016-05-29
    • 1970-01-01
    相关资源
    最近更新 更多