【问题标题】:Silverlight MVVM - How Can I Declaratively Bind a ComboBox in a DataGrid CellEditingTemplate using a ViewModel?Silverlight MVVM - 如何使用 ViewModel 在 DataGrid CellEditingTemplate 中声明性地绑定 ComboBox?
【发布时间】:2010-07-07 18:42:28
【问题描述】:

我正在尝试使用 ViewModel 在 DataGrid CellEditingTemplate 中以声明方式绑定 ComboBox。 ComboBox 未绑定。我做错了什么?

XAML:

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
    xmlns:data="clr-namespace:SilverlightApplication1"
    mc:Ignorable="d"
    x:Class="SilverlightApplication1.EmployeeDetail"
    Width="640" Height="480">

    <UserControl.Resources>
        <data:EmployeeDetailsViewModel
            x:Key="ViewModel"
            d:IsDataSource="True" />
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource ViewModel}}" Background="White">

        <sdk:DataGrid ItemsSource="{Binding Employees,Mode=TwoWay}" AutoGenerateColumns="False" CanUserSortColumns="True" CanUserReorderColumns="True" CanUserResizeColumns="True" GridLinesVisibility="All" Height="317" HorizontalAlignment="Left" Margin="12,136,0,0" Name="EmployeesGrid" VerticalAlignment="Top" Width="605">
            <sdk:DataGrid.Columns>


<!-- snipped from brevity -->

                <sdk:DataGridTemplateColumn Header="Status">
                    <sdk:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding EmployeeStatus.Description}" TextWrapping="Wrap"></TextBlock>
                        </DataTemplate>
                    </sdk:DataGridTemplateColumn.CellTemplate>
                    <sdk:DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{Binding Path=EmployeeStatuses}" SelectedItem="{Binding EmployeeStatus, Mode=TwoWay}" />
                        </DataTemplate>
                    </sdk:DataGridTemplateColumn.CellEditingTemplate>
                </sdk:DataGridTemplateColumn>

            </sdk:DataGrid.Columns>
        </sdk:DataGrid>
        <TextBlock x:Name="SearchLabel" HorizontalAlignment="Left" Margin="12,95,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="106" Height="34"><Run FontWeight="Bold" Text="Search By Name: "/><Run FontSize="9.333" Text="(Last, First)"/></TextBlock>
        <TextBox x:Name="SearchParam" HorizontalAlignment="Left" Margin="144,101,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="162"/>
        <Button x:Name="SearchButton" Content="Search" HorizontalAlignment="Right" Margin="0,102,242,0" VerticalAlignment="Top" Width="75" Click="SearchButton_Click"/>    


    </Grid>
</UserControl>

查看模型:

using System.Collections.ObjectModel;
using SilverlightApplication1.EmployeeService;
using SilverlightApplication1.ViewModels;

namespace SilverlightApplication1
{
    public class EmployeeDetailsViewModel : ViewModelBase
    {
        readonly IEmployeeServiceAgent _serviceAgent;
        ObservableCollection<EmployeeStatus> _employeeStatuses { get; set; }
        ObservableCollection<Employee> _employees { get; set; }

        public EmployeeDetailsViewModel() : this(new EmployeeServiceAgent()) { }
        public EmployeeDetailsViewModel(IEmployeeServiceAgent serviceAgent)
        {
            if (!IsDesignTime)
            {
                _serviceAgent = serviceAgent;
                GetAllEmployees();
                GetEmployeeStatuses();
            }

        }

        public ObservableCollection<Employee> Employees
        {
            get { return _employees; }
            set
            {
                if(_employees!=value)
                {
                    _employees = value;
                    OnNotifyPropertyChanged("Employees");
                }
            }
        }

        public ObservableCollection<EmployeeStatus> EmployeeStatuses
        {
            get { return _employeeStatuses; }
            set
            {
                if (_employeeStatuses != value)
                {
                    _employeeStatuses = value;
                    OnNotifyPropertyChanged("EmployeeStatuses");
                }
            }
        }

        private void GetAllEmployees()
        {
            _serviceAgent.GetAll((s, e) => Employees = e.Result);
        }

        private void GetEmployeeStatuses()
        {
            _serviceAgent.GetEmployeeStatuses((s, e) => EmployeeStatuses = e.Result);
        }

    }
}

更新:

这似乎是错误的,但我想出了如何通过重新引用 ItemSource Binding 中的 ViewModel 来使绑定工作:

<ComboBox ItemsSource="{Binding Source={StaticResource ViewModel},Path=EmployeeStatuses}"
                                      DisplayMemberPath="Description"
                                      SelectedItem="{Binding EmployeeStatus, Mode=TwoWay}"  />

但是,我现在遇到了 SelectedItem 未绑定的问题!我做错了什么?

【问题讨论】:

    标签: silverlight mvvm silverlight-4.0


    【解决方案1】:

    这个问题是人们遇到的一个常见问题。当您在列的数据模板中时,您不再绑定视图模型。此时,您的数据上下文是 EmployeeStatus 对象(它没有要绑定的 EmployeeStatuses 属性)。

    因此,要使组合框绑定起作用,您可以使用 ElementName=LayoutRoot 将树绑定到根 ViewModel。

    更新:以下是您的绑定的完整语法:

    {绑定 DataContext.EmployeeStatuses, ElementName=LayoutRoot}

    Update2:我实际上也遇到过这种情况,并且有一个workaround you have to implement 可以让元素名称绑定在数据网格中工作。

    【讨论】:

    • 您的意思是在 ComboBox 的 ItemsSource 中添加 ElementName=LayoutRoot 吗?我这样做了,但 ComboBox 仍然没有被绑定。
    • Bryant,我试过
    • 这似乎也没有帮助
    【解决方案2】:

    如果 Bryant 的解决方案不起作用(在 SL4 中),请使用静态资源。见此链接:http://blog.digitaltools.com/post/2011/05/06/Binding-a-Datagride28099s-ComboBox.aspx

    或者,通过在 xaml 中创建静态资源:http://forums.silverlight.net/post/370135.aspx

    【讨论】:

      猜你喜欢
      • 2021-07-07
      • 1970-01-01
      • 1970-01-01
      • 2013-12-17
      • 2011-11-24
      • 2014-09-12
      • 2011-03-10
      • 2010-12-21
      • 1970-01-01
      相关资源
      最近更新 更多