【问题标题】:WPF bind DataGrid combo box selected item to datacontext of selected DataGridRowWPF 将 DataGrid 组合框选定项绑定到选定 DataGridRow 的数据上下文
【发布时间】:2016-12-23 10:14:13
【问题描述】:

我有一个绑定到单独 ItemsSource 的 DataGridTemplateColumn 组合框似乎通过将此组合框绑定到另一个源它会更改 DataContext。

所以我在将组合框中所选项目的值绑定到 DataGrid 中所选行的 DataContext 时遇到问题。

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 错误:23:无法转换“{NewItemPlaceholder}” 从“NamedObject”类型到“en-US”文化类型“WorldData” 默认转换;考虑使用 Binding 的 Converter 属性。 NotSupportedException:'System.NotSupportedException: TypeConverter 无法从 MS.Internal.NamedObject 转换。在 System.ComponentModel.TypeConverter.GetConvertFromException(对象 值)在 System.ComponentModel.TypeConverter.ConvertFrom(ITypeDescriptorContext 上下文,CultureInfo 文化,对象值)在 MS.Internal.Data.DefaultValueConverter.ConvertHelper(对象 o,类型 destinationType、DependencyObject targetElement、CultureInfo 文化、 Boolean isForward)' 抛出异常:'System.NotSupportedException' 在 PresentationFramework.dll 中

似乎我应该使用类型转换器,但似乎我不应该这样做,因为我在 SO 上找到的很少

我想现在我将放弃并为组合框添加一个单独的框并绑定到 Datagrid 的选定项。我不觉得它很直观,所以如果你有任何聪明的想法,请。

【问题讨论】:

    标签: c# .net wpf 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;
                }
            }
        }
    }
    

    【讨论】:

    • 嗨 gomi42。刚看到这个。您能够绑定到 SelectedCountry 吗?您是否在 SelectedWorldData.Country 中放置了一个断点,以查看它是否在您选择一个国家/地区时真正命中?我还需要 CanUserAddRows 为真。感谢您的尝试
    • 对不起,我更新了我的第一个答案。现在我可以在Country 中设置一个中断,调试器就会停在那里。
    • 我忘了提到你可以将CanUserAddRows 设置为true。我将其关闭是因为要创建的新行显示了 Combobox,从 UX 角度来看这可能有点令人困惑。同样没有技术限制。
    • 这很奇怪。不知何故,我没有尝试过。但它有效,谢谢。我会接受你的回答。谢谢!
    猜你喜欢
    • 2012-06-26
    • 1970-01-01
    • 1970-01-01
    • 2011-05-11
    • 2022-10-07
    • 1970-01-01
    • 2018-07-27
    • 2023-03-16
    • 1970-01-01
    相关资源
    最近更新 更多