【问题标题】:Binding DatagridColumn to StaticResource pointing to ObservableCollection in WPF将 DatagridColumn 绑定到指向 WPF 中的 ObservableCollection 的 StaticResource
【发布时间】:2015-12-10 21:07:55
【问题描述】:

可以在 GridView 中手动将列 ItemsSource 绑定到 Enum,并将 selectedItemBinding 路径设置为 DataGrid.ItemsSource 的属性,如下所示:

<Window.Resources>
<ObjectDataProvider x:Key="DirectionEnum"
                    MethodName="GetValues"
                    ObjectType="{x:Type core:Enum}">
        <ObjectDataProvider.MethodParameters>
                <x:Type Type="local:Direction"/>
        </ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>

...

<DataGrid x:Name="DgvZlecNag" 
    AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridComboBoxColumn Header="Column0"
                 SelectedItemBinding="{Binding Direction}"
                 ItemsSource="{Binding Source={StaticResource DirectionEnum}}"/>

...

public enum Direction 
{
    Def = 0,
    Imp = 1,
    Exp = 2,
}

...

public MainWindow()
    {

        InitializeComponent();
        _orders = new ObservableCollection<ZlecNag>()
        {
            new ZlecNag() {
                Id = 1,
                Direction = Direction.Imp
                }
        }
    DgvZlecNag.ItemsSource = zlecenia;
    }

我想要做的是将列类似地绑定到 ObservableCollection,但它并不完全有效。 我尝试使用 column1 中的 staticResource 来执行此操作,它有效但不显示初始设置的值, 和column2中的本地observableCollection,它显示了初始值,但绑定属性的值不会随着在组合框中选择新项目而改变。 Column3 只是显示绑定的属性是否发生变化。

<Window x:Class="ZleceniaTransportowe2.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"
        xmlns:local="clr-namespace:ZleceniaTransportowe2"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:core="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="MainWindow" Height="500" Width="1200"
        >
<Window.Resources>
       <ObjectDataProvider x:Key="Clients"
                            MethodName="GetData"
                            ObjectType="{x:Type local:CollectionData}"
                            >
            <ObjectDataProvider.MethodParameters>
                <x:Type Type="local:CollectionData"/>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
        <local:IfNullConverter x:Key="IfNullConverter"/>
</Window.Resources>
        <DataGrid x:Name="DgvZlecNag" 
                  AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Id"
                                    Binding="{Binding Id, Mode=OneWay}"/>
                <DataGridComboBoxColumn Header="Column1"
                                        SelectedItemBinding="{Binding Path=Client, Mode=TwoWay}"
                                        ItemsSource="{Binding Source={StaticResource Clients}}"
                                        SelectedValuePath="Akronim"  DisplayMemberPath="Akronim"/>
                <DataGridTemplateColumn Header="Column2">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox SelectedValue="{Binding Client.Akronim, Mode=TwoWay}"
                                      DisplayMemberPath="Akronim"  SelectedValuePath="Akronim" SelectedItem="Client"
                                      ItemsSource= "{Binding Clients, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window }}}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTextColumn Header="column3"
                                    Binding="{Binding Client.Akronim, Mode=OneWay}"/>
            </DataGrid.Columns>

        </DataGrid>
</Window>

后面的代码:

namespace ZleceniaTransportowe2
{
    public partial class MainWindow: Window
    private ObservableCollection<ZlecNag> _orders;

    public ObservableCollection<Client> Clients {get;} = new ObservableCollection<Client>()
        {
            new Client()
            {
                Akronim = "Seifert",
            },
            new Client()
            {
                Akronim = "Cenergo",
            }
        };

        public MainWindow()
        {
            InitializeComponent();
            _orders = new ObservableCollection<ZlecNag>()
            {
                new ZlecNag() {
                    Id = 1,
                    Client = Clients.First(),

                },
               new ZlecNag() {
                    Id = 1,
                    Client = Clients[1],
                   }
                };
             DgvZlecNag.ItemsSource = _orders;
        }
    }
}

...

public class ZlecNag : INotifyPropertyChanged
{

    private Direction _direction;
    private Client _client;

    public Direction Direction
    {
        get { return _client; }
        set
        {
            _direction= value;
            OnPropertyChanged();
        }
    }

    public Client Client
    {
        get { return _client; }
        set
        {
            _client = value;
            OnPropertyChanged();
        }
    }
        public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

...

public class Client : INotifyPropertyChanged

{
    private int _gidNumer;
    private string _akronim;

    public int GidNumer
    {
        get { return _gidNumer; }
        set
        {
            _gidNumer = value;
            OnPropertyChanged();
        }
    }

    public string Akronim

    {
        get { return _akronim; }
        set
        {
            _akronim = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

...

column2 的 objectDataProvider 的数据类:

public class CollectionData
{
    public static ObservableCollection<Client> GetData(Type type = null)
    {
        var clients = new ObservableCollection<Client>()
        {
            new Client()
            {
                Akronim = "Seifert",
                GidNumer = 4654
            },
              new Kontrahent()
            {
                Akronim = "Cenergo",
                GidNumer = 4656
            }
        };
        return clients;
    }
}

请帮忙,我不知道如何解决这个问题。

【问题讨论】:

  • 请制作一个小型可行的应用程序,可以在概念上进行测试,类似于大型应用程序的小模型。
  • 好主意@AnjumSKhan,我已经在我的项目中添加了指向 zip 文件的链接。
  • 请将该链接作为评论发布。从问题中删除 Dropbox 链接,因为它不遵循 SO 准则。
  • 解决方案链接:dropbox.com/s/t1sepx7eofx6hyg/solution.zip?dl=0>

标签: c# wpf xaml data-binding


【解决方案1】:

您没有在 column2 中使用 Binding,而是您写了 SelectedItem="Client" ,请考虑在 SelectedItem 中进行绑定。

【讨论】:

  • 我已将其更改为SelectedItem="{Binding Path=Contractor, Mode=TwoWay}",但没有帮助。
  • 也应用 UpdateSourceTrigger=PropertyChanged
  • 它现在可以工作了,非常感谢@AnjumSKhan 我想知道为什么我必须专门应用这个属性,通常没有必要。
  • 那是因为不同控件的默认值不同。
  • @mdziadowiec ...并尝试查看实际问题以及您如何描述它。建议:在这里,您应该使用 DataGrid、列中的 ComboBox、类似的数据源等制作了一个小型独立应用程序,并检查它。
【解决方案2】:

显然它也可以在没有包含组合框的模板列的情况下完成。它看起来更好,因为单元格在被单击之前看起来不像一个组合框,因此它不会从其他 DataGrid 单元格中脱颖而出。

基于答案https://stackoverflow.com/a/5409984/2458980

<DataGridComboBoxColumn SelectedValueBinding="{Binding Contractor, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
                        DisplayMemberPath="Acronym">     
    <DataGridComboBoxColumn.ElementStyle>
         <Style TargetType="{x:Type ComboBox}">
             <Setter Property="ItemsSource" Value="{Binding Path=Contractors, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
         </Style>
     </DataGridComboBoxColumn.ElementStyle>
     <DataGridComboBoxColumn.EditingElementStyle>
         <Style TargetType="{x:Type ComboBox}">
             <Setter Property="ItemsSource" Value="{Binding Path=Contractors, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
         </Style>
     </DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>

【讨论】:

    猜你喜欢
    • 2017-09-29
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 2010-10-27
    • 1970-01-01
    • 1970-01-01
    • 2013-12-31
    • 2014-05-25
    相关资源
    最近更新 更多