Silverlight MVVM - Как я могу декларативно связать ComboBox в DataGrid CellEditingTemplate, используя ViewModel? - PullRequest
0 голосов
/ 07 июля 2010

Я пытаюсь декларативно связать ComboBox в DataGrid CellEditingTemplate, используя ViewModel. 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);
        }

    }
}

Обновление:

Это кажется неправильным, но я выяснил, как заставить работать привязку, повторно ссылаясь на ViewModel в привязке ItemSource:

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

Однако сейчас у меня проблема с тем, что SelectedItem не привязан! Что я делаю не так?

Ответы [ 2 ]

2 голосов
/ 07 июля 2010

Проблема обычная, с которой сталкиваются люди. Когда вы находитесь в шаблоне данных столбца, вы больше не привязываете модель представления. На этом этапе ваш контекст данных - это объект EmployeeStatus (у которого нет свойства EmployeeStatuses для привязки).

Таким образом, чтобы привязка комбинированного списка работала, вы можете использовать ElementName = LayoutRoot, чтобы связать дерево обратно с корневой ViewModel.

Обновление: Вот полный синтаксис для вашей привязки:

{Binding DataContext.EmployeeStatuses, ElementName = LayoutRoot}

Обновление 2: Я на самом деле тоже столкнулся с этим, и существует обходной путь, который необходимо реализовать , чтобы получить привязку имени элемента для работы внутри сетки данных.

0 голосов
/ 01 октября 2012

Если решение Брайанта не работает (в SL4), используйте статические ресурсы. Смотрите эту ссылку: http://blog.digitaltools.com/post/2011/05/06/Binding-a-Datagride28099s-ComboBox.aspx

Или, создав статический ресурс в xaml: http://forums.silverlight.net/post/370135.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...