2016-12-23 2 views
1

У меня есть поле со списком DataGridTemplateColumn, которое привязывается к отдельному элементу ItemsSource. Кажется, привязывая этот combobox к другому источнику, он меняет DataContext.WPF bind DataGrid combo box selected item to datacontext выбранного DataGridRow

Так что у меня возникают проблемы, связывающие значение выбранного элемента в поле со списком с DataContext выбранной строки в DataGrid.

XAML:

<DataGrid HorizontalAlignment="Left" ItemsSource="{Binding Path=WorldDataList}" SelectedItem="{Binding SelectedWorldData}">   
    <DataGridTemplateColumn Header="Country" > 
     <DataGridTemplateColumn.CellTemplate > 
      <DataTemplate> 
       <ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type StackPanel}},Path=DataContext.Countries}" 
          SelectedItem="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=SelectedItem.Country}" 
          SelectedIndex="0"/> 
      </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
    </DataGridTemplateColumn> 
</DataGrid> 

C#:

class WorldDataViewModel : ObservableObject 
{ 
    private ObservableCollection<WorldData> _worldDataList = new ObservableCollection<WorldData>(); 
    public ObservableCollection<WorldData> WorldDataList 
    { 
     get { return _worldDataList; } 
     set 
     { 
      Set(ref _worldDataList, value); 
     } 
    } 

    public List<string> Countries {get;set;} 

    private WorldData worldData; 
    private WorldData SelectedWorldData 
    { 
     get{return worldData;} 
     set 
     { 
      Set(ref worldData, value); 
     } 
    } 
} 

class WorldData : ObservableObject 
{ 
    private string country; 
    public string Country 
    { 
     get{return country;} 
     set 
     { 
      Set(ref country, value); 
     } 
} 

я получаю исключение:

System.Windows.Data Error: 23 : Cannot convert '{NewItemPlaceholder}' from type 'NamedObject' to type 'WorldData' for 'en-US' culture with default conversions; consider using Converter property of Binding. NotSupportedException:'System.NotSupportedException: TypeConverter cannot convert from MS.Internal.NamedObject. at System.ComponentModel.TypeConverter.GetConvertFromException(Object value) at System.ComponentModel.TypeConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value) at MS.Internal.Data.DefaultValueConverter.ConvertHelper(Object o, Type destinationType, DependencyObject targetElement, CultureInfo culture, Boolean isForward)' Exception thrown: 'System.NotSupportedException' in PresentationFramework.dll

Похоже, я должен использовать конвертер типа, но, кажется, я не должен сделайте это с самых маленьких, которые я смог найти на SO

Я думаю, что на данный момент я просто сдаюсь и добавлю отдельный блок для combobox и привяжу к выбранному элементу Datagrid. Я не считаю это интуитивным, поэтому, если у вас есть умные идеи.

ответ

1

Это мое полное тестовое приложение, которое возвращает выбранную страну в WorldData. Без UpdateSourceTrigger на SelectedItem он не работает.

<Window 
    x:Class="ComboboxInDataGrid.MainWindow" 
    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" 
    Title="MainWindow" 
    Width="525" 
    Height="350" 
    mc:Ignorable="d"> 
    <Grid> 
     <DataGrid x:Name="me" 
      HorizontalAlignment="Left" 
      AutoGenerateColumns="False" 
      CanUserAddRows="False" 
      ItemsSource="{Binding Path=WorldDataList}" 
      SelectedItem="{Binding SelectedWorldData}"> 
      <DataGrid.Columns> 
       <DataGridTemplateColumn Header="Country"> 
        <DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <Grid> 
           <ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, 
                           AncestorType={x:Type DataGrid}}, 
                   Path=DataContext.Countries}" 
              SelectedItem="{Binding Path=Country, 
                   Mode=TwoWay, 
                   UpdateSourceTrigger=PropertyChanged}" /> 
          </Grid> 
         </DataTemplate> 
        </DataGridTemplateColumn.CellTemplate> 
       </DataGridTemplateColumn> 
      </DataGrid.Columns> 
     </DataGrid> 
    </Grid> 
</Window> 


using System.Collections.Generic; 
using System.Windows; 

namespace ComboboxInDataGrid 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      DataContext = new WorldDataViewModel(); 
      InitializeComponent(); 
     } 
    } 

    class WorldDataViewModel 
    { 
     public WorldDataViewModel() 
     { 
      var c1 = "USA"; 
      var c2 = "Canada"; 
      var c3 = "Brasil"; 
      var c4 = "Brasfsdfsil"; 

      Countries = new List<string>(); 
      Countries.Add (c1); 
      Countries.Add (c2); 
      Countries.Add (c3); 
      Countries.Add (c4); 

      _worldDataList.Add (new WorldData { Index = 1, Country = c2 }); 
      _worldDataList.Add (new WorldData { Index = 2, Country = c3 }); 
      _worldDataList.Add (new WorldData { Index = 3, Country = c4 }); 
     } 

     private List<WorldData> _worldDataList = new List<WorldData>(); 
     public List<WorldData> WorldDataList 
     { 
      get 
      { 
       return _worldDataList; 
      } 
      set 
      { 
       _worldDataList = value; 

      } 
     } 

     public List<string> Countries { get; set; } 

     private WorldData worldData; 
     public WorldData SelectedWorldData 
     { 
      get 
      { 
       return worldData; 
      } 

      set 
      { 
       worldData = value; 
      } 
     } 
    } 

    public class WorldData 
    { 
     public int Index { get; set; } 

     private string country; 
     public string Country 
     { 
      get { return country; } 
      set 
      { 
       country = value; 
      } 
     } 
    } 
} 
+0

Hi gomi42. Просто увидев это. Вы смогли привязаться к SelectedCountry? Вы поставили точку останова в SelectedWorldData.Country, чтобы увидеть, действительно ли она отображается, когда вы выбираете страну? Мне также нужно, чтобы CanUserAddRows был правдой. Спасибо за вашу попытку, хотя –

+0

Прошу прощения, я обновил свой первый ответ. Теперь я могу установить перерыв в 'Country', и отладчик останавливается там. – gomi42

+0

Я забыл упомянуть, что вы можете установить «CanUserAddRows» в true. Я отключил его, потому что новая создаваемая строка показывает Combobox, которая может быть немного запутанной с точки зрения UX. Опять же нет технических ограничений. – gomi42