2

有没有人有将 ComboBox 绑定到 DataGrid 的选定项的示例?我已经尝试了很多方法,但我似乎无法让它发挥作用。我对 MVVM 相当陌生,所以我做错了。任何帮助,将不胜感激。我将组合框所在的网格的数据上下文设置为数据网格,但是当我从数据网格中选择一行时,组合框不会改变。所有文本框都使用来自数据网格的数据填充,但组合框不会更改。有问题的组合框是 cmbRoles。

谢谢,

RG

这是 XAML:

<UserControl x:Class="Compliance.Views.UserAdministrationView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:Compliance"
         xmlns:views="clr-namespace:Compliance.Views"
         xmlns:helpers="clr-namespace:Compliance.Helpers"
         xmlns:vm="clr-namespace:Compliance.ViewModels"
         xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
         mc:Ignorable="d" 
         d:DesignHeight="1000" d:DesignWidth="800">
<UserControl.Resources>
    <helpers:ActiveStatusConverter x:Key="ActiveStatusConverter"/>
</UserControl.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="0" Margin="15">
        <Label Content="User" Height="25" FontSize="14" HorizontalContentAlignment="Center" />
        <Grid HorizontalAlignment="Center" VerticalAlignment="Top" DataContext="{Binding ElementName=usersDG, Path=SelectedItem}">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" MinHeight="35" />
            </Grid.RowDefinitions>
            <telerik:Label Content="User Name: " Grid.Column="0" Grid.Row="0" HorizontalAlignment="Right" VerticalAlignment="Center" />
            <TextBox Grid.Column="1" Grid.Row="0" MinHeight="23" HorizontalAlignment="Left" VerticalAlignment="Center" MinWidth="180" MaxWidth="180" >
                <TextBox.Text>
                    <Binding Path="UserName" Mode="TwoWay" ValidatesOnDataErrors="True" NotifyOnValidationError="True"/>
                </TextBox.Text>                    
            </TextBox> 
            <telerik:Label Content="First Name: " Grid.Column="2" Grid.Row="0" HorizontalAlignment="Right" VerticalAlignment="Center" />
            <TextBox Grid.Column="3" Grid.Row="0" MinHeight="23" HorizontalAlignment="Left" VerticalAlignment="Center" MinWidth="180" MaxWidth="180">
            <TextBox.Text>
                <Binding Path="FirstName" Mode="TwoWay" ValidatesOnDataErrors="True" NotifyOnValidationError="True"/>
            </TextBox.Text>
            </TextBox>
            <telerik:Label Content="Last Name: " Grid.Column="4" Grid.Row="0" HorizontalAlignment="Right" VerticalAlignment="Center" />
            <TextBox Grid.Column="5" Grid.Row="0" MinHeight="23" HorizontalAlignment="Left" VerticalAlignment="Center" MinWidth="180" MaxWidth="180">
            <TextBox.Text>
                <Binding Path="LastName" Mode="TwoWay" ValidatesOnDataErrors="True" NotifyOnValidationError="True"/>
            </TextBox.Text>
            </TextBox>
            <telerik:Label Content="Email: " Grid.Column="0" Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Center" />
            <TextBox Grid.Column="1" Grid.Row="1" MinHeight="23" HorizontalAlignment="Left" VerticalAlignment="Center" MinWidth="180" MaxWidth="180">
                <TextBox.Text>
                    <Binding Path="Email" Mode="TwoWay" ValidatesOnDataErrors="True" NotifyOnValidationError="True"/>
                </TextBox.Text>
            </TextBox>
            <telerik:Label Content="Active Status: " Grid.Column="2" Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Center" />
            <telerik:RadComboBox x:Name="comBoxActiveStatus" Grid.Column="3" Grid.Row="1" MinHeight="23" MinWidth="180" HorizontalAlignment="Left" VerticalAlignment="Center"
                    SelectedItem="{Binding Path=ActiveStatus, 
                                    Converter={StaticResource ResourceKey=ActiveStatusConverter}, 
                                    Mode=TwoWay, 
                                    ValidatesOnExceptions=True, 
                                    NotifyOnValidationError=True}">
            </telerik:RadComboBox>
            <telerik:Label Content="Role: " Grid.Column="4" Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Center" />
            <telerik:RadComboBox x:Name="cmbRoles" DisplayMemberPath="RoleName" 
                        Grid.Column="5" 
                        Grid.ColumnSpan="3"
                        Grid.Row="1" 
                        MinHeight="23" 
                        HorizontalAlignment="Left" 
                        ItemsSource="{Binding}" 
                        Margin="5" 
                        VerticalAlignment="Center" 
                        MinWidth="180" 
                        SelectedItem="{Binding RoleName}"
                        IsSynchronizedWithCurrentItem="True">
            </telerik:RadComboBox>
            <Button Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="3" Content="Save User" Width="100"  />
            <Button Grid.Column="4" Grid.Row="2" Grid.ColumnSpan="3" Content="Add User"  Width="100"  />
        </Grid>
    </StackPanel>
    <Border CornerRadius="10" BorderThickness="5" Grid.Row="1" VerticalAlignment="Top" HorizontalAlignment="Center">
        <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Label Content="Users" Grid.Row="0" Height="25" FontSize="14" HorizontalContentAlignment="Center" />
            <telerik:RadGridView x:Name="usersDG" ItemsSource="{Binding Users}" AutoGenerateColumns="False" ShowGroupPanel="False" IsReadOnly="True">
                <telerik:RadGridView.Columns>
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding UserName}" Header="User Name" />
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding FirstName}" Header="First Name" />
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding LastName}" Header="Last Name" />
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding Email}" Header="Email" />
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding Role.RoleName}" Header="Role Name" />
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding ActiveStatus, Converter={StaticResource ActiveStatusConverter}}" Header="Active Status" />
                </telerik:RadGridView.Columns>
            </telerik:RadGridView>
        </Grid>
    </Border>
</Grid>

4

2 回答 2

2

扩展并对上面的 Hannish 的回答采取不同的看法,我也假设您使用的是 Master Details 类型排列,您希望将 Details DataContext 设置为 DataGrid Selected Row。

在这个设置中,我也遇到了很多关于 ComboBox Binding 的问题。

我的应用程序不使用 Telerik 控件,但我倾向于为 DataGrid 选定行创建一个属性,并将我的详细信息绑定到此。

DataGrid XAML 类似于;

<DataGrid x:Name="grdResults" 
    DataContext="{Binding DataGridDataContextCollection}" 
    ItemsSource="{Binding}"
    SelectedItem="{Binding DataContext.SelectedRow, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">

我这样做是因为我已经为运行 DataGrid DataContext 中的项目的行设置了行为。

然后我也有一个选定的组合框项目的属性,并将组合框绑定到这个。

对于 ComboBox ItemSource,问题在于,您需要将 ComboBox 绑定到的项目的 ObservableCollection,但这些当然不会是您的 DataGrid 选定行的成员,而反过来您的详细信息 DataContext。

所以要绑定ComboBox ItemSource 和SelectedItem,必须引用View 的DataContext,而不是Details 的DataContext。

如果您在 DataGrid DataContext 中有它可用,还将 ComboBox Text 属性绑定到 DataGrid SelectedRow Name 值,假设两者相同!这有助于更新 DataGrid 也已更新。

我用于 ComboBox 的 XAML 类似于;

<ComboBox x:Name="cmbRoles" 
    SelectedItem="{Binding DataContext.SelectedRole, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" 
    SelectedValuePath="Role_ID" 
    SelectedValue="{Binding Role_ID, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"
    ItemsSource="{Binding DataContext.RoleItems, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" 
    Text="{Binding RoleName, Mode=TwoWay}"
    DisplayMemberPath="RoleName" 
    IsSynchronizedWithCurrentItem="True" 
    HorizontalAlignment="Left"/>

为了 100% 确定,然后我通过在 ComboBox SelectedItem Setter 中设置 DataGrid SelectedRow ID 值将 ComboBox SelectedItem 同步到 DataGrid SelectedRow。这当然不是绝对必要的。

我希望这有帮助!

于 2013-01-03T20:07:19.627 回答
0

如果我理解正确,您有一个包含所有用户的 RadGridView,以及某种详细信息表单,您可以在其中编辑所选行的值。

所以,你必须修改几件事:

1:combobox中的ItemsSource设置为{Binding},所以它只会绑定到其父元素的datacontext来获取items列表。在这种情况下,父级是 Grid,其 DataContext 设置(正确)到 RadGrid 的选定项(这里:DataContext="{Binding ElementName=usersDG, Path=SelectedItem}",没关系)。

问题是您必须使用可能的角色列表填充 ComboBox 的 ItemsSource。我通常对此类列表使用静态 ObservableCollection(因此我确保它们在整个应用程序中都是相同的)。像这样的东西:

ItemsSource="{x:静态本地:Lists.RolesList}"

您可能有一个枚举或其他东西,但重要的是您使用所有可能选择的选项填充 ItemsSource 属性。

2:由于您将使用 Role 对象填充组合框中的列表,因此 SelectedItem 必须绑定到此类对象,该对象必须作为公共属性(使用 INPC 或 DependecyProperty)存在于 User 对象中。您需要像这样设置它:

SelectedItem="{绑定角色,模式=TwoWay}"

请记住,您的组合的数据上下文是一个用户对象,如在 RadGrid 中选择的那样。用户类必须具有属性 Role。

我想这样就可以了,如果你还有什么问题,请告诉我。最好的祝福!

于 2013-01-03T19:02:03.390 回答