简体   繁体   English

XAML将可观察的集合绑定到DataGrid

[英]XAML Binding Observable Collection to DataGrid

I'm having trouble databinding based on other properties. 我在基于其他属性进行数据绑定时遇到麻烦。 My combobox is working fine, but the datagrids aren't. 我的组合框工作正常,但数据网格却没有。 I'm was trying to bind the window to the codebehind using DataContext="{Binding RelativeSource={RelativeSource Self}}" so I could have design time Intellisense, but I sort of got it using x:Name:"_Window" 我正在尝试使用DataContext="{Binding RelativeSource={RelativeSource Self}}"将窗口绑定到背后的代码,这样我可以设计Intellisense,但是我使用x:Name:"_Window"

The model for HRRM has lots of entities, and I know that that the properties I'm trying to bind too are spelt correctly etc. But I can't figure out why the DataGrid won't show the employees. HRRM的模型有很多实体,而且我知道我尝试绑定的属性也拼写正确等。但是我不知道为什么DataGrid不会显示雇员。 I've also ensured that the data is being placed in the observable collection, and I've tried binding the items source just to ListEmployees and SmsEmployees and nothing I've tried has worked. 我还确保将数据放置在可观察的集合中,并且尝试将项目源仅绑定到ListEmployees和SmsEmployees,而我尝试过的任何方法都没有起作用。 This is the last bit of code I have tried. 这是我尝试过的最后一部分代码。

<Window x:Class="GUI.Employees.Misc.SendSms"
    x:Name="_Window"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Send SMS" Height="525" Width="1000" DataContext="{Binding ElementName=_Window}">

<Grid>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="270*" />
        <ColumnDefinition Width="150" />
        <ColumnDefinition Width="270*" />
    </Grid.ColumnDefinitions>
    <ComboBox Grid.Column="0" x:Name="cmbCompany" DisplayMemberPath="Name" ItemsSource="{Binding Path=Companies, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"  Margin="10,10,10,0" VerticalAlignment="Top" SelectionChanged="cmbCompany_SelectionChanged"/>
    <DataGrid Grid.Column="0" x:Name="dgEmployees" Margin="10,37,10,10" IsReadOnly="True"  AutoGenerateColumns="False" ItemsSource="{Binding Path=ListEmployees, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window} }">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Company" Binding="{Binding HRCo }"/>
            <DataGridTextColumn Header="First Name" Binding="{Binding FirstName}" />
            <DataGridTextColumn Header="Last Name" Binding="{Binding LastName}"/>
            <DataGridTextColumn Header="Craft" Binding="{Binding StdCraft}"/>
        </DataGrid.Columns>
    </DataGrid>
    <DataGrid x:Name="dgSendSms" Margin="10,37,10,10" IsReadOnly="True" Grid.Column="2" ItemsSource="{Binding  SmsEmployees, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window} }">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Company" Binding="{Binding HRCo}"/>
            <DataGridTextColumn Header="First Name" Binding="{Binding FirstName}" />
            <DataGridTextColumn Header="Last Name" Binding="{Binding LastName}"/>
            <DataGridTextColumn Header="Craft" Binding="{Binding StdCraft}"/>
        </DataGrid.Columns>
    </DataGrid>
    <Button x:Name="cmdMoveAllHired" Content="&gt;&gt;" Margin="10,85,10,0" VerticalAlignment="Top" Grid.Column="1"
            Click="cmdMoveAllHired_Click" />
    <Button x:Name="cmdReturnSingleItem" Content="&gt;" Margin="10,122,10,0" VerticalAlignment="Top"
            Grid.Column="1"  Click="cmdReturnSingleItem_Click" />
    <Button x:Name="cmdMoveAllReturned" Content="&lt;&lt;" Margin="10,196,10,0" VerticalAlignment="Top"
            Grid.Column="1"  Click="cmdMoveAllReturned_Click" />
    <Button x:Name="cmdHireSingleItem" Content="&lt;" Margin="10,159,10,0" VerticalAlignment="Top" Grid.Column="1"
             Click="cmdHireSingleItem_Click" />
    <Button x:Name="cmdGenerate" Content="Generate" Grid.Column="1" Margin="10,0,10,10"
            VerticalAlignment="Bottom" Click="cmdGenerate_Click" Visibility="Collapsed" />
    <Button x:Name="cmdBack" Content="Back" Grid.Column="1" HorizontalAlignment="Left" Margin="10,249,0,0"
            VerticalAlignment="Top" Width="130" Click="cmdBack_Click" />

    <Button x:Name="cmdSendSMS" Content="Send SMS" Grid.Column="1" HorizontalAlignment="Left" Margin="10,316,0,0" VerticalAlignment="Top" Width="130" Click="cmdSendSMS_Click"/>

</Grid>

namespace GUI.Employees.Misc
{
public partial class SendSms
{
    public ObservableCollection<HQCO> Companies { get; set; }

    public ObservableCollection<HRRM> ListEmployees { get; set; }

    private ObservableCollection<HRRM> _smsEmployees;

    public ObservableCollection<HRRM> SmsEmployees {
        get { return _smsEmployees; }
        set { _smsEmployees = value;
        }
    }

    public SendSms()
    {
        InitializeComponent();
        Companies = new ObservableCollection<HQCO>(HQCO.GetActivePRCompanies());
        Companies.Insert(0, new HQCO { HQCo = 0, Name = "All" });
        // cmbCompany.SelectedItem = _companies.Single(x=>x.HQCo == 0);
        SmsEmployees = new ObservableCollection<HRRM>();
        ChangeCompany();
    }
    private void ChangeCompany()
    {
        if (((HQCO)cmbCompany.SelectedItem)?.HQCo == 0)
            foreach (var co in Companies)
                co.IsChecked = true;
        else
            foreach (var co in Companies)
                if (((HQCO)cmbCompany.SelectedItem) == co)
                    co.IsChecked = true;
                else
                    co.IsChecked = false;

        ListEmployees = new ObservableCollection<HRRM>(Facade.GetEmployeePhoneNumbers(Companies.ToList(), false).OrderBy(x => x.SortName));
    }
}

I don't believe your ListEmployees ItemsSource will update the DataGrid because it is not a DependencyProperty or you have not implemented INotifyPropertyChanged . 我不相信您的ListEmployees ItemsSource将更新DataGrid因为它不是DependencyProperty或您尚未实现INotifyPropertyChanged It is not updating because you are assigning the property a new instance. 它没有更新,因为您正在为属性分配一个新实例。

Instead try adding this to your constructor: 而是尝试将其添加到您的构造函数中:

ListEmployees = new ObservableCollection<HRRM>();

And this to your ChangeCompany method: 这是您的ChangeCompany方法:

foreach (var employee in Facade.GetEmployeePhoneNumbers(Companies.ToList(), false).OrderBy(x => x.SortName))
{
    ListEmployees.Add(employee);
}

The above will actually make use of the ObservableCollection and it should then update the UI. 上面的内容实际上将使用ObservableCollection ,然后应更新UI。

I think your problem is how you assign the DataContext of your Window. 我认为您的问题是如何分配Window的DataContext。 In your XAML, add a reference to the namespace so the Window can find your SendSms viewmodel, and then either assign the DataContext property in XAML (see below), or in the code-behind of your Window. 在XAML中,添加对命名空间的引用,以便Window可以找到您的SendSms视图模型,然后在XAML中(请参见下文)或在Window的代码后面分配DataContext属性。 If you set the DataContext this way, you shouldnt need to use RelativeSource when binding to the SendSms viewmodel, but if you want see changes, you also need to make sure the classes your observable collections are populated with implements INotifyPropertyChanged. 如果以这种方式设置DataContext,则在绑定到SendSms视图模型时不需要使用RelativeSource,但是如果要查看更改,则还需要确保可观察性集合的类填充有INotifyPropertyChanged实现。

<Window x:Name="_Window"
        xmlns:local="clr-namespace:GUI.Employees.Misc" >

 <!--  set the DataContext of this Window to an instance of SendSms  -->
<Window.DataContext>
    <local:SendSms />
</Window.DataContext>

<DataGrid ItemsSource="{Binding ListEmployees}">
   ...
</DataGrid>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM