Я добавил диалог в мое приложение WPF. Вот Xaml:Когда привязка свойства ItemsSource генерирует элементы?
<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, ничего не выбирается. Когда диалог наконец откроется, в любом из ComboBoxes ничего не выбрано.
Я использовал этот шаблон в ряде UserControls
на MainWindow
моего приложения с успехом, но это первый раз, когда я использовал его в диалоговом окне. Где подходящее место для вызова метода UpdateChoices
и для установки SelectedIndex
свойств ComboBoxes
?
P.S. Я не включил детали метода UpdateChoices, потому что это не относится к вопросу.
Я знаю образец. У меня нет времени переделывать все мое приложение в шаблон MVVM прямо сейчас, так как мы должны выйти на 6/22. Однако после релиза я собираюсь потратить некоторое время на переработку экрана за раз. –