1

我在我的 WPF 应用程序中添加了一个对话框。这是 Xaml:

<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都填完后,ItemsComboBoxes. 当我将SelectedIndex属性设置为 0 时,没有选择任何内容。当对话框最终打开时,任何一个组合框中都没有选择任何内容。

我已经成功地在我的应用程序中使用了这种模式UserControlsMainWindow但这是我第一次在对话框中使用它。调用UpdateChoices方法和设置SelectedIndex属性的正确位置在哪里ComboBoxes

PS 我没有包含 UpdateChoices 方法的详细信息,因为它与问题无关。

4

3 回答 3

0

您的 DataContext 设置为 HotList,它与您尝试访问的属性处于同一级别。要么将 DataContext 更改为整个对话框,要么将 observable 集合移动到 HotList 对象中。

于 2012-05-21T21:04:52.197 回答
0

我不知道绑定的问题是什么,但我摆脱了它,只是在对话框的事件处理程序中设置控件的ItemsSource属性。现在一切正常。ComboBoxLoaded

于 2012-06-07T17:19:01.157 回答
0

查看 MVVM 模式。几乎不需要任何代码,并且您可以获得可测试的代码。

于 2012-06-07T17:44:33.823 回答