代码之家  ›  专栏  ›  技术社区  ›  Edward Tanguay

WPF/Silverlight中显示适当数据的简单下拉列表的最佳方式是什么?

  •  0
  • Edward Tanguay  · 技术社区  · 16 年前

    下面是一个简单的WPF应用程序,它显示 订单最多的客户

    扩展此WPF应用程序的最佳方法是什么,以便用户可以从下拉列表中进行选择,例如:

    • 订单最多的客户
    • 按城市划分的客户
    • 按州划分的客户

    以下是一些想法:

    1. 有许多dockpanel,其中加载了所有由事件处理程序显示/折叠的数据( 急功近利 )
    2. 视图模型 它以某种方式用ViewModel填充ContentControl,然后通过XAML中的转换器将ViewModel附加到视图
    3. 使用 最有价值球员
    4. 或者有没有办法做到这一点 简单代码隐藏 但是只有当用户在下拉列表中选择选择时,才会加载数据

    在WPF/Silverlight应用程序中,如何解决这一常见的业务线问题,即客户单击控制按钮,屏幕上的一个区域会显示相应的信息?

    <Window x:Class="TestLinqToSql123.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="500">
        <Window.Resources>
            <DataTemplate x:Key="CustomerTemplate">
                <TextBlock>
                    <TextBlock.Text>
                        <MultiBinding StringFormat="{}The customer {0} lives in {1} and has {2} orders.">
                            <Binding Path="Name"/>
                            <Binding Path="City"/>
                            <Binding Path="NumberOfOrders"/>
                        </MultiBinding>
                    </TextBlock.Text>
                </TextBlock>
            </DataTemplate>
    
        </Window.Resources>
        <DockPanel>
            <Border 
                Background="Orange"
                CornerRadius="5"
                Margin="10"
                Padding="10">
                <ScrollViewer>
                    <StackPanel>
                    <TextBlock Text="Customers with the most orders:"
                       Margin="0 0 0 10"
                       FontSize="18"/>
    
                    <ItemsControl x:Name="TheList"
                            ItemTemplate="{StaticResource CustomerTemplate}"/>
                    </StackPanel>
                </ScrollViewer>
            </Border>
        </DockPanel>
    </Window>
    

    代码隐藏:

    using System.Windows;
    using TestLinqToSql123.Models;
    using System.Linq;
    
    namespace TestLinqToSql123
    {
        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
    
                NorthwindDataContext db = new NorthwindDataContext();
    
                var customers = from c in db.Customers
                                orderby c.Orders.Count descending
                                select new
                                {
                                    Name = c.ContactName,
                                    c.City,
                                    NumberOfOrders = c.Orders.Count
                                };
                TheList.ItemsSource = customers;
            }
        }
    }
    
    2 回复  |  直到 16 年前
        1
  •  2
  •   Martin Liversage    16 年前

    我将使用在WPF和Silverlight应用程序中非常流行的Model-View-ViewModel模式。

    模型

    customer类是模型中的一个实体。您还需要一个存储库或服务类来根据各种条件返回客户集合。在Silverlight中,数据是异步检索的,这使事情有点复杂。通过为此存储库或服务类创建接口或抽象基类,可以在不使用数据库的情况下测试ViewModel类。您可以模拟一些测试数据。

    视图模型

    ViewModel使用数据绑定连接到视图,它必须实现 INotifyPropertyChanged 和/或 INotifyCollectionChanged 或者使用依赖属性公开其数据。前一种方法通常更易于实现和测试。

    在您的示例中,似乎只想使用不同的排序条件对同一个集合进行排序。然后,ViewModel就是客户对象的集合。显示客户非常简单,ViewModel可以直接包含客户实体对象。在更复杂的场景中,例如可以编辑客户,则需要创建客户视图模型。

    您的ViewModel可以从 ObservableCollection<T> CollectionView . 后面的is类在Silverlight中不可用,您必须通过实现 ICollectionView .

    SortOrder 属性设置为ViewModel,并在该属性更改时调用集合。

    视图

    这是一个 UserControl 并使用XAML实现。有些人发现视图中完全没有代码隐藏非常重要,但是Silverlight中缺少命令需要一些代码隐藏或类似命令的附加属性(PRISM在Silverlight中支持这一点)。

    这个 DataContext 视图的元素设置为ViewModel,然后使用数据绑定将视图的元素绑定到ViewModel的各个部分。按钮和其他活动的用户界面控件连接到ViewModel上的方法等。在WPF中可以使用命令,但在Silverlight中,您需要一些代码隐藏或类似于命令的东西。

    当用户单击视图中的控件时,该操作将被路由到ViewModel,或者作为对方法的调用或对属性的更改。然后更新ViewModel,视图到ViewModel的数据绑定确保向用户显示更新的信息。

        2
  •  1
  •   Ian Oakes    16 年前

    你可以在里面做这个 简单代码隐藏 很容易。在边框上方添加以下组合框。

    <ComboBox 
        x:Name="SelectionCombo" 
        DockPanel.Dock="Top" 
        SelectionChanged="ComboBox_SelectionChanged"
        >
        <ComboBoxItem x:Name="MostOrders">Customers with the most orders</ComboBoxItem>
        <ComboBoxItem x:Name="LeastOrders">Customers with the least orders</ComboBoxItem>
        <ComboBoxItem x:Name="ByCity">Customers by city</ComboBoxItem>
        <ComboBoxItem x:Name="ByState">Customers by state</ComboBoxItem>
    </ComboBox>
    

    然后在代码隐藏中添加以下事件处理程序

    private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        ComboBoxItem item = (ComboBoxItem)e.AddedItems[0];
        if (item == MostOrders)
            GetByMostOrders();
        else if (item == LeastOrders)
            GetByLeastOrders();
        else if (item == ByCity)
            GetByCity();
        else if (item == ByState)
            GetByState();
    }
    

    然后创建填充组合的方法

    private void GetByMostOrders()
    {
        NorthwindDataContext db = new NorthwindDataContext();
    
        var customers = from c in db.Customers
                        orderby c.Orders.Count descending
                        select new
                        {
                            Name = c.ContactName,
                            c.City,
                            NumberOfOrders = c.Orders.Count
                        };
        TheList.ItemsSource = customers;
    }
    

    如果你不这么做的话,也许我应该听听你的建议。