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
}

}

このコードをデバッグすると、2 つのコードにObservableCollectionsデータが取り込まれていることがわかります。これはUpdateChoicesメソッドで発生します。UpdateChoices上記のコードのどこにあるかと同様に、コンストラクターにも 呼び出しを入れました。

問題は、2 つObservableCollectionsが入力された後、 に何もないItemsことComboBoxesです。SelectedIndexプロパティを 0に設定すると、何も選択されません。ダイアログが最終的に開くと、どちらのコンボボックスでも何も選択されていません。

私はこのパターンをアプリケーションの多くでUserControls使用MainWindowして成功しましたが、ダイアログで使用したのはこれが初めてです。UpdateChoicesメソッドを呼び出してSelectedIndexプロパティを設定するのに適切な場所はどこComboBoxesですか?

PS UpdateChoices メソッドの詳細は質問に関係ないため、含めませんでした。

4

3 に答える 3

0

MVVMパターンを確認してください。コードビハインドはほとんど必要なく、テスト可能なコードを取得できます。

于 2012-06-07T17:44:33.823 に答える
0

DataContext は、アクセスしようとしているプロパティと同じレベルの HotList に設定されています。DataContext をダイアログ全体に変更するか、監視可能なコレクションを HotList オブジェクトに移動します。

于 2012-05-21T21:04:52.197 に答える
0

バインディングの問題が何であったかはわかりませんが、それを取り除き、ダイアログのイベント ハンドラーでコントロールのItemsSourceプロパティを設定するだけで済みました。すべてが機能するようになりました。ComboBoxLoaded

于 2012-06-07T17:19:01.157 に答える