2012-05-21 64 views
1

我已經添加了一個對話框到我的WPF應用程序。這裏的XAML中:什麼時候對ItemsSource屬性的綁定生成Items?

<cs:CarSystemDialog x:Class="CarSystem.CustomControls.EditHotListDialog" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:cs="clr-namespace:CarSystem.CustomControls" 
        DataContext="{Binding Path=HotList, RelativeSource={RelativeSource Self}}" 
        Height="265" 
        Loaded="EditHotListDialog_Loaded" 
        MaxHeight="665" 
        MaxWidth="1200" 
        SizeToContent="WidthAndHeight" 
        cs:ThemeSelector.CurrentThemeDictionary="{Binding Path=TimeOfDayTheme, RelativeSource={RelativeSource Self}}" 
        Width="850" 
        WindowStartupLocation="CenterOwner" > 

    <cs:CarSystemDialog.Resources> 
     <cs:BooleanToVisibilityConverter x:Key="BoolToVisibility" True="Visible" False="Collapsed" /> 
     <cs:CaseToVisibilityConverter x:Key="CaseToVisibilityConverter" /> 
    </cs:CarSystemDialog.Resources> 

    <Grid Background="{DynamicResource ContentBackground}" FocusManager.IsFocusScope="True" Name="LayoutRoot"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="Auto" /> 
      <ColumnDefinition Width="*" /> 
      <ColumnDefinition Width="Auto" /> 
      <ColumnDefinition Width="*" /> 
     </Grid.ColumnDefinitions> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto" /> 
      <RowDefinition Height="Auto" /> 
      <RowDefinition Height="Auto" /> 
      <RowDefinition Height="Auto" /> 
     </Grid.RowDefinitions> 

     <TextBlock FontSize="16" 
        FontWeight="Bold" 
        Foreground="{DynamicResource TextForeground}" 
        Grid.Column="0" 
        Grid.Row="0" 
        HorizontalAlignment="Right" 
        Margin="5" 
        Text="Source:" 
        VerticalAlignment="Center" /> 
     <TextBox AcceptsTab="False" 
       AcceptsReturn="False" 
       BorderBrush="{DynamicResource ControlBorder}" 
       BorderThickness="2" 
       FontSize="16" 
       FontWeight="Bold" 
       Foreground="{DynamicResource UnfocusedForeground}" 
       Grid.Column="1" 
       Grid.Row="0" 
       Margin="5" 
       MaxLength="80" 
       MaxLines="1" 
       Name="HotListNameBox" 
       TabIndex="0" 
       Text="{Binding Path=Name, Mode=TwoWay}" 
       VerticalAlignment="Center" /> 

     <TextBlock FontSize="16" 
        FontWeight="Bold" 
        Foreground="{DynamicResource TextForeground}" 
        Grid.Column="2" 
        HorizontalAlignment="Right" 
        Margin="5" 
        Text="List Type:" 
        VerticalAlignment="Center" /> 
     <ComboBox BorderBrush="{DynamicResource PlateInfoBorder}" 
        DisplayMemberPath="Value" 
        FontSize="16" 
        FontWeight="Bold" 
        Grid.Column="3" 
        ItemsSource="{Binding Path=ListTypes, RelativeSource={RelativeSource AncestorType={x:Type cs:EditHotListDialog}}}" 
        Margin="5" 
        Name="ListTypePicker" 
        SelectedValue="{Binding Path=ListTypeId, Mode=TwoWay}" 
        SelectedValuePath="Key" 
        TabIndex="1" /> 

     <TextBlock FontSize="16" 
        FontWeight="Bold" 
        Foreground="{DynamicResource TextForeground}" 
        Grid.Column="0" 
        Grid.Row="1" 
        HorizontalAlignment="Right" 
        Margin="5" 
        Text="Domain:" 
        VerticalAlignment="Center" /> 
     <ComboBox BorderBrush="{DynamicResource PlateInfoBorder}" 
        DisplayMemberPath="Value" 
        FontSize="16" 
        FontWeight="Bold" 
        Grid.Column="1" 
        Grid.Row="1" 
        ItemsSource="{Binding Path=Domains, RelativeSource={RelativeSource AncestorType={x:Type cs:EditHotListDialog}}}" 
        Margin="5" 
        Name="DomainPicker" 
        SelectedValue="{Binding Path=DomainId, Mode=TwoWay}" 
        SelectedValuePath="Key" 
        TabIndex="1" /> 

     <StackPanel Grid.Column="0" 
        Grid.ColumnSpan="4" 
        Grid.Row="2" 
        HorizontalAlignment="Center" 
        Orientation="Horizontal"> 
      <Button Background="{DynamicResource ButtonBackground}" 
        Click="OkButton_Click" 
        Content="OK" 
        FontSize="18" 
        FontWeight="Bold" 
        Foreground="{DynamicResource ButtonForeground}" 
        Height="50" 
        IsDefault="True" 
        IsEnabled="{Binding Path=CanSave, RelativeSource={RelativeSource AncestorType={x:Type cs:EditHotListDialog}}}" 
        Margin="5" 
        Name="OkButton" 
        Width="100"/> 
      <Button Background="{DynamicResource ButtonBackground}" 
        Content="Cancel" 
        FontSize="18" 
        FontWeight="Bold" 
        Foreground="{DynamicResource ButtonForeground}" 
        Height="50" 
        IsCancel="True" 
        Margin="5" 
        Name="CancelButton" 
        Width="100" /> 
     </StackPanel> 

    </Grid> 
</cs:CarSystemDialog> 

而這裏的代碼背後:

public partial class EditHotListDialog : CarSystemDialog, INotifyPropertyChanged { 

    public static readonly DependencyProperty CanSaveProperty = 
     DependencyProperty.Register("CanSave", typeof(bool), typeof(EditHotListDialog), new PropertyMetadata(false)); 

    public static readonly DependencyProperty HotListProperty = 
     DependencyProperty.Register("HotList", typeof(HotListViewModel), typeof(EditHotListDialog), 
            new PropertyMetadata(null, new PropertyChangedCallback(OnHotListChanged))); 

    public bool CanSave { 
     get { return (bool) GetValue(CanSaveProperty); } 
     set { SetValue(CanSaveProperty, value); } 
    } 

    public ObservableCollection<ItemChoice<int?>> Domains { get; set; } 

    public HotListViewModel HotList { 
     get { return (HotListViewModel) GetValue(HotListProperty); } 
     set { SetValue(HotListProperty, value); } 
     } 

    public ObservableCollection<ItemChoice<int?>> ListTypes { get; set; } 

    public EditHotListDialog() { 
     InitializeComponent(); 

     Domains = new ObservableCollection<ItemChoice<int?>>(); 
     ListTypes = new ObservableCollection<ItemChoice<int?>>(); 

     Domains .Add(new ItemChoice<int?> { Key = null, Value = "-- Pick a Domain --"}); 
     ListTypes.Add(new ItemChoice<int?> { Key = null, Value = "-- Pick a List Type --" }); 
     KeywordCache.KeywordCacheUpdated += KeywordCacheUpdated; 
    } 

    private void EditHotListDialog_Loaded(object sender, RoutedEventArgs e) { 
     UpdateChoices(); 

      DomainPicker.SelectedIndex = 0; 
     ListTypePicker.SelectedIndex = 0; 
    } 

    void HotList_PropertyChanged(object sender, PropertyChangedEventArgs e) { 
     HotListViewModel hotList = sender as HotListViewModel; 
     CanSave = !(string.IsNullOrEmpty(hotList.Name) || string.IsNullOrWhiteSpace(hotList.Name)) && hotList.ListTypeId > 0 && hotList.DomainId > 0; 
    } 

    private void OkButton_Click(object sender, RoutedEventArgs e) { 
     if (ValidateHotList()) { 
      DialogResult = true; 
      Close(); 
     } 
     e.Handled = true; 
    } 

    private void OnHotListChanged(HotListViewModel oldHotList, HotListViewModel newHotList) { 
     if (oldHotList != null) { 
      oldHotList.PropertyChanged -= HotList_PropertyChanged; 
     } 
     if (newHotList != null) { 
      newHotList.PropertyChanged += HotList_PropertyChanged; 
     } 
    } 
    private static void OnHotListChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { 
     EditHotListDialog dialog = d as EditHotListDialog; 
     dialog.OnHotListChanged(e.OldValue as HotListViewModel, e.NewValue as HotListViewModel); 
    } 

    private void UpdateChoices() { 
       . . . 
    } 

    private bool ValidateHotList() { 
     if (string.IsNullOrEmpty(HotListNameBox.Text.Trim())) { 
      CarSystemMessageBox.Show("Please enter a name for the Hot List.", "Please Name the Hot List", MessageBoxButton.OK, MessageBoxImage.None); 
      return false; 
     } 

     if (ListTypePicker.SelectedIndex <= 0) { 
      CarSystemMessageBox.Show("Please select the List Type from the drop down that specifies what type of Hot List this is.", "Please Specify a List Type", MessageBoxButton.OK, MessageBoxImage.None); 
      return false; 
     } 
     if (DomainPicker.SelectedIndex <= 0) { 
      CarSystemMessageBox.Show("Please select the Domain from the drop down that this Hot List Entry belongs to.", "Please Specify a Domain", MessageBoxButton.OK, MessageBoxImage.None); 
      return false; 
     } 
     return true; 
    } 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected void RaisePropertyChangedEvent(string propertyName) { 
     if (PropertyChanged != null) { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    #endregion 
} 

}

當我調試代碼,我看到兩個ObservableCollections得到填充數據。這發生在UpdateChoices方法中。我在構造函數中將UpdateChoices的調用以及它在上面的代碼中的位置。

問題是,在填充了兩個ObservableCollections之後,ComboBoxes中沒有Items。當我將SelectedIndex屬性設置爲0時,沒有任何選擇。當對話框終於打開時,任何一個組合框都不會被選中。

我已經在我的應用程序的MainWindow上使用了UserControls這個模式,但是這是我第一次在對話框中使用它。哪裏可以撥打UpdateChoices方法並設置的SelectedIndex屬性?

P.S.我沒有包含UpdateChoices方法的細節,因爲它與問題無關。

回答

0

我不知道是什麼的問題結合了,但我擺脫它,只是設置ComboBox控制的ItemsSource屬性在對話框的Loaded事件處理程序。現在一切正常。

0

您的DataContext設置爲HotList,它與您嘗試訪問的屬性處於同一級別。將DataContext更改爲整個對話框,或將可觀察集合移入HotList對象。

0

檢出MVVM模式。幾乎不需要代碼,你可以獲得可測試的代碼。

+0

我知道這種模式。我沒有時間將我的整個應用程序重新編譯爲MVVM模式,因爲我們將於6/22發佈。然而,在發佈之後,我會花費一些時間重新修改屏幕。 –

相關問題