【问题标题】:Inter-related combo boxes in WPFWPF中相互关联的组合框
【发布时间】:2015-09-01 03:16:52
【问题描述】:

我在我的项目中使用 WPF C#。 我的 UI 包含 4 个组合框,每个组合框都将由数据库中的值加载。 现在一次显示所有 4 个组合框。 但我想要做的是,第一个组合框 1 应该可见/显示,然后用户选择一个值说 val1,然后第二个组合框应该是可见的,它应该包含基于在组合框 1 中选择的 val1 的值(来自数据库),并且很快。 组合框应该与之前的组合框相互关联。

如何在 WPF 中完成这项任务?

一些 XAML 代码: 请选择:

    <Label Grid.Row="1">combobox1 :</Label>
    <ComboBox  Name="PL" Grid.Row="1" Grid.Column="1" Loaded="ComboBox_PLLoaded" SelectionChanged="ComboBox_PLSelectionChanged" />

    <Label Grid.Row="2" HorizontalAlignment="Right">combobox2:</Label>
    <ComboBox Name="Re" Grid.Row="2" Grid.Column="1" VerticalAlignment="Top"  Loaded="ComboBox_RCLoaded" SelectionChanged="ComboBox_RCSelectionChanged"/>

    <Label Grid.Row="3" Margin="89.216,0,60.581,26" Grid.RowSpan="2">combobox3 :</Label>
    <ComboBox Name="CT" Grid.Row="3" Grid.Column="1" Loaded="ComboBox_RCLoaded" SelectionChanged="ComboBox_RCSelectionChanged"/>

    <Label Grid.Row="4" HorizontalAlignment="Right">combobox4 :</Label>
    <ComboBox Name="PT" Grid.Row="4" Grid.Column="1" />

   </Grid>

【问题讨论】:

  • 到目前为止你的努力是什么?你遇到了什么问题?
  • 我可以在combobox1中加载数据,用户可以选择一个值,但是现在我执行一个查询,根据在combobox中选择的值过滤数据。我想在combobox2中加载它。combobox 2应该是仅在组合框 1 中选择值后显示
  • 请给我们看一些代码,删除不相关的数据库内容。
  • 用一些代码编辑问题
  • 一些代码隐藏也很好。到目前为止,您的 XAML 似乎足以满足您的要求,您只需要控制事件处理程序上的组合 VisibilityItemsSource ......虽然最好的方法是使用绑定,而不是事件。

标签: wpf user-interface combobox wpf-controls database-connectivity


【解决方案1】:

您可以使用BooleanToVisibilityConverter Class 来显示和隐藏各种ComboBoxes 以及您代码后面或视图模型中的许多bool 属性。您可以从相关的SelectionChanged 事件处理程序中将相关的设置为true。举个简单的例子:

XAML:

<ComboBox Name="Re" Grid.Row="2" Grid.Column="1" VerticalAlignment="Top"  
    Loaded="ComboBox_RCLoaded" SelectionChanged="ComboBox_RCSelectionChanged" 
    Visibility="{StaticResource BooleanToVisibilityConverter}" />

代码背后:

private void ComboBox_PLSelectionChanged(object sender, SelectionChangedEventArgs args)
{
    ComboBox comboBox = sender as ComboBox;
    var data = GetDataForNextComboBox(comboBox.SelectedItem);
    NextComboBox.ItemsSource = data;
    // Make next ComboBox visible using BooleanToVisibilityConverter
    BoolPropertyForComboBox2 = true;
}

显然,您仍然需要在 Resources 部分中添加对 BooleanToVisibilityConverter 的引用,声明新的 bool 属性并实现示例中的 GetDataForNextComboBox 数据访问方法。

【讨论】:

  • 同意,虽然我们谈论的是代码隐藏,但我会直接设置NextComboBox.Visibility。如果谈论 MVVM,我会删除 SelectionChanged 事件处理并创建一个绑定到另一个属性。
  • 我在组合框 2 中尝试了 Visibility="Hidden" 属性,并尝试在加载组合框 1 后使其可见。但是一旦我从combobox1中选择一个值,就应该加载combobox2,因为它基于该值从数据库中获取数据。但是现在我观察到的是 combobox2 的 Loaded="ComboBox_RCLoaded" 在我在 combobox1 中选择一个值之前尝试加载它。我可以让组合框的 Load 属性等待它我从 combobox1 中选择一个值吗?
  • @beginner ComboBox 将被加载,但您可以根据在 Selectionchanged 事件中选择的 comboBox1 设置可见性。有一个方法来填充 ComboBox2 的项目,并在 ComboBox1 的 Selectionchanged 事件中调用该方法。否则请在 ComboBox2 的 Loaded 事件中告诉我们您想要做什么
  • 您不需要在Loaded 事件处理程序中做任何事情。如果您像我的示例一样使用BooleanToVisibilityConverter,那么您只需将数据绑定bool 属性设置为false 以隐藏ComboBox。然后,您只需将其设置为true 即可显示它。很简单。
【解决方案2】:

如果您没有使用 MVVM,那么 Sheridan 给出的答案会对您有所帮助,因为您可以在该事件本身中设置 Visibility,而不是使用 bool 变量和 BoolToVisibility 转换器(正如almulo所说)。

如果你或任何使用 MVVM 的人遇到这个问题,可以看看我的回答。

我刚刚添加了代码,根据 ComboBox1 的 SelectedItem 设置可见性,并根据 ComboBox1 的 SelectedItem 设置 ItemsSource。

在 ViewModel 中要做的事情。

  1. 有一个绑定到 ComboBox1 的 SelectedItem 的属性。
  2. 有一个集合属性,需要根据 ComboBox1 的 SelectedItem 绑定到 ComboBox2。
  3. 每当 SelectedItemCombo1 发生变化时,更新绑定到 ComboBox2 的 ItemsSource 的集合属性(您可以在 Combo1 的 SelectedItem 的 PropertyChanged 事件中执行此操作,否则您可以在 VM 中为 SelectionChanged 编写命令)

找到 ComboBox2 的 XAML 代码,我添加了转换器来检查 ComboBox1 的 SelectedItem,如果为 null,则 ComboBox2 将不可见。

<ComboBox Name="Re" Grid.Row="2" Grid.Column="1" VerticalAlignment="Top"  ItemsSoure="{Binding combo1Selected}"
    Visibility="{Binding ElementName=PL, Path=SelectedItem, Converter={StaticResource selectedItemToVisibilityConverter}}"> />

转换器如下:

public class SelectedItemToVisibility : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value == null)
                return Visibility.Collapsed;
            else
                return Visibility.Visible;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

希望对你有所帮助。

【讨论】:

    猜你喜欢
    • 2014-01-20
    • 1970-01-01
    • 2015-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多