2017-09-04 235 views
0

我遇到了基於其他屬性的數據綁定問題。我的combobox工作正常,但datagrids不是。我試圖窗口結合使用 DataContext="{Binding RelativeSource={RelativeSource Self}}",所以我可以有時間設計的智能感知代碼隱藏,但我把它用x:Name:"_Window"XAML綁定可觀察集合到DataGrid

爲HRRM模型有很多實體類的了,我知道的是,屬性我想要綁定太拼寫正確等,但我不明白爲什麼DataGrid不會顯示員工。我也確保數據被放置在可觀察的集合中,並且我已經嘗試將項源綁定到ListEmployees和SmsEmployees,並且我沒有嘗試過任何工作。這是我試過的最後一段代碼。

<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)); 
    } 
} 
+0

如果你使用MVVM你可能不會有這個問題 – MickyD

回答

0

我認爲你的問題是你如何分配你的窗口的DataContext。在您的XAML中,添加對命名空間的引用,以便Window可以找到您的SendSms viewmodel,然後在XAML中分配DataContext屬性(請參見下文),或者在Window的代碼隱藏中。如果以這種方式設置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> 

+0

感謝您的回答,雖然這是導致堆棧溢出作爲我假設它是創造自身的萬份。這是一個非常古老的項目,我現在試圖修改爲使用綁定,但我可能只是考慮將其直接轉換爲MVVM。 – Phalanx

+0

好的。如果你沒有使用MVVM,那麼完全刪除所有的DataContext和RelativeSource使用,並簡單地在代碼後面的代碼中設置ItemSource,如下所示: dgEmployees.ItemSource sendSms.ListEmployees;如果你確實想用MVVM試試我上面的方法。 SendSms構造函數應該只針對您實例化的每個窗口調用一次。無論您是否使用MVVM方法,我都會確保這種情況。 – Fredrik

+0

_「...添加對命名空間的引用,以便Window可以找到您的SendSms viewmodel ...」 - - OP的** SendSms **是他的**視圖**而不是他的** VM ** – MickyD

1

我不相信你的ListEmployeesItemsSource將更新DataGrid,因爲它不是一個DependencyProperty或者你還沒有實現INotifyPropertyChanged。它不會更新,因爲您正在爲該屬性分配一個新實例。

而是嘗試添加這對你的構造:

ListEmployees = new ObservableCollection<HRRM>(); 

這對您的ChangeCompany方法:

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

以上,實際上利用ObservableCollection,然後它應該更新UI。