【问题标题】:Combobox inside datagrid selected item数据网格选定项内的组合框
【发布时间】:2011-08-25 20:20:22
【问题描述】:

我有一个包含一列组合框的数据网格。 数据网格 itemssource 是 UserInfo 对象的集合。

UserInfo 类的定义如下:

public class UserInfo
{

    public string User { get; set; }

    public UserRole Role { get; set; }


}
public enum UserRole
{

    None = 0,

    Administrator = 1,

    Reviewer = 2,
}

当我拥有集合时,我将它分配给数据网格:

private void svc_GetAllUsersCompleted(object sender, ServiceReference1.GetAllUsersCompletedEventArgs args)
    {
        ObservableCollection<UserInfo> users = args.Result;
        UsersPage.dataGrid1.ItemsSource = users;
    }

这是数据网格的 xaml:

<data:DataGrid Margin="5,25,5,17" AutoGenerateColumns="False" AllowDrop="True" Name="dataGrid1"  SelectionMode="Single" UseLayoutRounding="True" SelectionChanged="dataGrid1_SelectionChanged" Grid.RowSpan="2" Grid.ColumnSpan="2" Grid.Row="1" ItemsSource="{Binding}" >
        <data:DataGrid.Resources>
            <DataTemplate x:Key="UserRoleTemplate">
                <Border BorderThickness="0,0,0,0" BorderBrush="#6FBDE8">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                        </Grid.ColumnDefinitions>
                        <ComboBox Name="cmbUserRoleTypes" VerticalAlignment="Center" Grid.Column="0" Loaded="cmbUserRoleTypes_Loaded" SelectedIndex="0" ItemsSource="{Binding GetListOfRoles,Source={StaticResource rList}}" SelectedValue="{Binding Role, Mode=TwoWay}" ></ComboBox>
                    </Grid>
                </Border>
            </DataTemplate>
            <DataTemplate x:Key="UserNameTemplate">
                <Border BorderThickness="0,0,0,0" BorderBrush="#6FBDE8">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                        </Grid.ColumnDefinitions>
                        <TextBlock Name="txtUserName" VerticalAlignment="Center" Grid.Column="0" Loaded="cmbUserRoleTypes_Loaded" Text="{Binding Path=Name}" ></TextBlock>
                    </Grid>
                </Border>
            </DataTemplate>
        </data:DataGrid.Resources>
        <data:DataGrid.Columns>
            <data:DataGridTextColumn Header="User Name" Width="200"
            Binding="{Binding User}" />
            <data:DataGridTemplateColumn Header="User Role" Width="200"
            CellTemplate="{StaticResource UserRoleTemplate}" />
            <!--<data:DataGridTextColumn Header="Assigned Issues"  />-->
        </data:DataGrid.Columns>
    </data:DataGrid>

使用来自具有所有用户角色的类的集合填充组合:这是 xaml:

<UserControl.Resources>
        <local:RolesTypes x:Key="rList">
        </local:RolesTypes>
</UserControl:Resources>

这是拥有该集合的类:

public class RolesTypes
{
    public List<string> GetListOfRoles
    {

        get
        {

            List<string> RolesList = new List<string>();
            RolesList.Add("administrator");
            RolesList.Add("reviewer");
            return RolesList;
        }



    }
}

我的问题是: 该组合很好地填充了角色列表,但是当我收到 usersinfo 集合时,我希望每个用户都在其匹配的组合中选择其角色并且它不会发生。尽管用户角色确实存在于角色列表中,但组合中没有选择任何角色。 有什么想法吗?

【问题讨论】:

    标签: silverlight data-binding


    【解决方案1】:

    CAVEAT:这会使用组合框填充网格并将组合框设置为用户角色。它是在后面的代码中完成的,我认为这违反了所有 MVVM 原则,但我无法绑定工作。 (也许一些绑定专家可以修改它)也就是说,如果你使用它,你可能应该在组合框上附加一个处理程序,以便在组合框更改时更新你的用户角色。希望这会有所帮助,祝你好运!

    修改 cmbUserRoleTypes_Loaded 以填充组合框,并删除转换器代码。请注意,不同的角色值是硬编码的,您可能希望使其通用。

    修改为包含组合框,抱歉在我不得不离开之前匆忙完成并且没有重新阅读您的帖子。我真的不喜欢它必须在代码隐藏中设置组合框,似乎应该有一些方法来数据绑定它。注意:我在将组合框选择绑定到用户记录时遇到了麻烦,但至少这会在其中获得填充的组合框。希望对您有所帮助。

    这里是 xaml

    <UserControl xmlns:data="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"  x:Class="StackOverflowProblems.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:StackOverflowProblems"
        mc:Ignorable="d"
        d:DesignHeight="300" d:DesignWidth="400">
    
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="auto" />
                <RowDefinition Height="auto" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
    
            <Button Content="Populate users" Click="btn_Click" HorizontalAlignment="Left"></Button>
            <StackPanel Grid.Row="1" Orientation="Horizontal">
                <data:Label  Content="Roles:"/>
                <ComboBox VerticalAlignment="Center" Name="myComboBox"  ></ComboBox>
            </StackPanel>
            <Grid Grid.Row="2" x:Name="LayoutRoot" Background="White">
            <data:DataGrid Margin="5,25,5,17" AutoGenerateColumns="False" AllowDrop="True" Name="dataGrid1"  SelectionMode="Single" UseLayoutRounding="True" SelectionChanged="dataGrid1_SelectionChanged" Grid.RowSpan="2" Grid.ColumnSpan="2" Grid.Row="1" ItemsSource="{Binding}" >
                <data:DataGrid.Resources>
    
                    <DataTemplate x:Key="UserRoleTemplate">
                        <Border BorderThickness="0,0,0,0" BorderBrush="#6FBDE8">
                                <ComboBox  VerticalAlignment="Center"  Loaded="cmbUserRoleTypes_Loaded"  >
                                    </ComboBox>
                        </Border>
                    </DataTemplate>
    
                    <DataTemplate x:Key="UserNameTemplate">
                        <Border BorderThickness="0,0,0,0" BorderBrush="#6FBDE8">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition />
                                </Grid.ColumnDefinitions>
                                <TextBlock Name="txtUserName" VerticalAlignment="Center" Grid.Column="0" Loaded="cmbUserRoleTypes_Loaded" Text="{Binding Path=Name}" ></TextBlock>
                            </Grid>
                        </Border>
                    </DataTemplate>
                </data:DataGrid.Resources>
    
                <data:DataGrid.Columns>
                    <data:DataGridTextColumn Header="User Name" Width="200" Binding="{Binding User}" />
                    <data:DataGridTemplateColumn Header="User Role" Width="200" CellTemplate="{StaticResource UserRoleTemplate}" />
                </data:DataGrid.Columns>
            </data:DataGrid>
    
        </Grid>
        </Grid>
    
    
    </UserControl>
    

    这是后面的代码 使用系统; 使用 System.Collections.ObjectModel; 使用 System.Reflection; 使用 System.Windows; 使用 System.Windows.Controls;

        namespace StackOverflowProblems
        {
            public partial class MainPage : UserControl
            {
                ObservableCollection<UserInfo> users = new ObservableCollection<UserInfo>();
                ObservableCollection<string> roles = new ObservableCollection<string>();
    
                public MainPage()
                {
                    InitializeComponent();
                    LayoutRoot.DataContext = this;
    
                    InitializeRoles();
                }
    
                public void InitializeRoles()
                {
                    // turn enumeration into a collection of strings
                    Type enumType = typeof(UserRole);  
    
                    foreach (FieldInfo fieldInfo in enumType.GetFields(BindingFlags.Public | BindingFlags.Static))  
                    {
                        roles.Add(fieldInfo.Name.ToString());
                    }
    
                    myComboBox.ItemsSource = roles;
                    myComboBox.SelectedIndex = 0;
                }
    
                public void svc_GetAllUsersCompleted()
                {
                    users.Add(new UserInfo("Fred", UserRole.Administrator));
                    users.Add(new UserInfo("George", UserRole.None));
                    users.Add(new UserInfo("Mary", UserRole.Reviewer));
                    dataGrid1.ItemsSource = users;
                }
    
                private void dataGrid1_SelectionChanged(object sender, SelectionChangedEventArgs e)
                {
    
                }
    
                private void cmbUserRoleTypes_Loaded(object sender, RoutedEventArgs e)
                {
                    ComboBox bx = (ComboBox)sender;
                    UserInfo ui = (UserInfo)bx.Tag;
    
                    bx.ItemsSource = roles;
    
                    int userRoleIndex = 0;
                    switch (ui.Role)
                    {
                        case UserRole.None:
                            userRoleIndex = 0;
                            break;
                        case UserRole.Administrator:
                            userRoleIndex = 1;
                            break;
                        case UserRole.Reviewer:
                            userRoleIndex = 2;
                            break;
                        default:
                            throw new Exception("Invalid Role Detected");
                    }
                    bx.SelectedIndex = userRoleIndex;
    
                }
    
                private void btn_Click(object sender, RoutedEventArgs e)
                {
                    svc_GetAllUsersCompleted();
                } 
    
            }
        }
    

    这里是支持类文件 使用系统; 使用 System.ComponentModel; 使用 System.Globalization; 使用 System.Windows.Data;

    namespace StackOverflowProblems
    {
        public class UserInfo : INotifyPropertyChanged
        {
            #region INotifyPropertyChanged
            public event PropertyChangedEventHandler PropertyChanged;
            protected void NotifyPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
            #endregion
    
            private string _User = "";
            public string User
            {
                get { return _User; }
                set
                {
                    if (_User != value)
                    {
                        _User = value;
                        NotifyPropertyChanged("User");
                    }
                }
            }
    
    
            private UserRole _Role = UserRole.None;
            public UserRole Role
            {
                get { return _Role; }
                set
                {
                    if (_Role != value)
                    {
                        _Role = value;
                        NotifyPropertyChanged("User");
                    }
                }
            }
            public UserInfo(string user, UserRole role)
            {
                User = user;
                Role = role;
            }
        }
    
        public enum UserRole
        {
    
            None = 0,
    
            Administrator = 1,
    
            Reviewer = 2,
        }
    }
    

    【讨论】:

    • 您发布的示例根本没有在模板列中使用组合框。它使用两个文本列。我的问题是我需要一个带有选定值的组合框列。
    • 修改了使用组合框的示例
    • 谢谢布拉德,但主要问题仍然存在 :) 我仍然无法在组合框中选择一个与其相应的用户信息相匹配的值。
    • 好的,再来一次,这次它用用户的角色填充组合框。
    【解决方案2】:

    您的 SelectedValue 也很有可能在 ItemsSource 获得 GetListOfRoles 的值之前接收它的值。

    如果我没记错的话,这可能会导致将“值”设置为 ItemsSource 中尚不存在的项目。

    【讨论】:

      猜你喜欢
      • 2011-07-06
      • 2011-06-05
      • 2015-07-19
      • 2013-09-07
      • 2016-07-19
      • 2013-03-12
      • 1970-01-01
      • 2015-07-30
      • 1970-01-01
      相关资源
      最近更新 更多