10

を使用してWPFウィンドウを作成していますDataGridが、グリッドの下部に空白の「新しいアイテム」行を表示して、グリッドに新しいアイテムを追加できるようにします。何らかの理由で、ウィンドウのグリッドに空白行が表示されません。これが私が作成に使用したマークアップですDataGrid

<toolkit:DataGrid  x:Name="ProjectTasksDataGrid" 
                   DockPanel.Dock="Top" 
                   Style="{DynamicResource {x:Static res:SharedResources.FsBlueGridKey}}"
                   AutoGenerateColumns="False" 
                   ItemsSource="{Binding SelectedProject.Tasks}" 
                   RowHeaderWidth="0" 
                   MouseMove="OnStartDrag" 
                   DragEnter="OnCheckDropTarget" 
                   DragOver="OnCheckDropTarget" 
                   DragLeave="OnCheckDropTarget" 
                   Drop="OnDrop" 
                   InitializingNewItem="ProjectTasksDataGrid_InitializingNewItem">
    <toolkit:DataGrid.Columns>
        <toolkit:DataGridCheckBoxColumn HeaderTemplate="{DynamicResource {x:Static res:SharedResources.CheckmarkHeaderKey}}" Width="25" Binding="{Binding Completed}" IsReadOnly="false"/>
        <toolkit:DataGridTextColumn Header="Days" Width="75" Binding="{Binding NumDays}" IsReadOnly="false"/>
        <toolkit:DataGridTextColumn Header="Due Date" Width="75" Binding="{Binding DueDate, Converter={StaticResource standardDateConverter}}" IsReadOnly="false"/>
        <toolkit:DataGridTextColumn Header="Description" Width="*" Binding="{Binding Description}" IsReadOnly="false"/>
    </toolkit:DataGrid.Columns>
</toolkit:DataGrid>

空白行が表示されない理由がわかりません。私は明らかなもの(IsReadOnly="false"CanUserAddRows="True")を試しましたが、運がありませんでした。空白行が無効になっている理由はありますか?ご協力いただきありがとうございます。

4

7 に答える 7

6

やっとこいつに戻った。受け入れられた回答 (緑色のチェックマーク) を変更するつもりはありませんが、問題の原因は次のとおりです。

My View Model はドメイン クラスをラップして、WPF に必要なインフラストラクチャを提供します。私が使用するラップ メソッドに関するCodeProject の記事を書きました。これには、2 つの型パラメーターを持つコレクション クラスが含まれています。

VmCollection<VM, DM>

ここで、DMはラップされたドメイン クラスであり、DMはそれをラップする WPF クラスです。

何らかの奇妙な理由で、コレクション クラスに 2 番目の型パラメーターがあると、WPF DataGrid が編集不能になることが判明しました。修正は、2 番目の型パラメーターを削除することです。

なぜこれが機能するのかは言えませんが、機能しているだけです。他の誰かが道を進むのに役立つことを願っています。

于 2009-10-28T13:10:10.240 に答える
5

Vincent Sibalは、DataGridに新しい行を追加するために必要なものを説明する記事を投稿しました。かなりの数の可能性があり、そのほとんどは、に使用しているコレクションのタイプによって異なりますSelectedProject.Tasks

「タスク」が読み取り専用のコレクションではなく、DataGridで新しいアイテムを正しく追加できるようにするために必要なインターフェイス(前のリンクで説明)の1つをサポートしていることを確認することをお勧めします。

于 2009-09-23T16:05:14.373 に答える
5

私の意見では、これは DataGrid のバグです。 Mike Blandford のリンクは、最終的に問題が何であるかを理解するのに役立ちました: DataGrid は、実際のオブジェクトがバインドされるまで、行の型を認識しません。データ グリッドが列の型を認識しないため、編集行が表示されません。厳密に型指定されたコレクションをバインドするとうまくいくと思うかもしれませんが、そうではありません。

Mike Blandford の回答を拡張するには、最初に空のコレクションを割り当ててから、行を追加および削除する必要があります。例えば、

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        // data binding
        dataGridUsers.ItemsSource = GetMembershipUsers();
        EntRefUserDataSet.EntRefUserDataTable dt = (EntRefUserDataSet.EntRefUserDataTable)dataGridUsers.ItemsSource;
        // hack to force edit row to appear for empty collections
        if (dt.Rows.Count == 0)
        {
            dt.AddEntRefUserRow("", "", false, false);
            dt.Rows[0].Delete();
        }
    }
于 2011-09-06T14:31:19.640 に答える
1

空のアイテムを ItemsSource に追加してから削除します。これを行った後、CanUserAddRows を true に戻す必要がある場合があります。私はここでこの解決策を読みました:(JarreyとRick Roenによる投稿)

ItemsSource を DataTable の DefaultView に設定し、ビューが空だったときに、この問題が発生しました。ただし、列は定義されているため、それらを取得できたはずです。へー。

于 2010-11-27T17:32:26.643 に答える
0

私にとって、編集可能な非同期を実装する最良の方法DataGridは次のようになります。

モデルを見る:

 public class UserTextMainViewModel : ViewModelBase
{ 
    private bool _isBusy;
    public bool IsBusy
    {
        get { return _isBusy; }
        set
        {
            this._isBusy = value;
            OnPropertyChanged();
        }
    }




    private bool _isSearchActive;
    private bool _isLoading;


    private string _searchInput;
    public string SearchInput
    {
        get { return _searchInput; }
        set
        {
            _searchInput = value;
            OnPropertyChanged();

            _isSearchActive = !string.IsNullOrEmpty(value);
            ApplySearch();
        }
    }

    private ListCollectionView _translationsView;
    public ListCollectionView TranslationsView
    {
        get
        {
            if (_translationsView == null)
            {
                OnRefreshRequired();
            }

            return _translationsView;
        }
        set
        {
            _translationsView = value;
            OnPropertyChanged();
        }
    }


    private void ApplySearch()
    {
        var view = TranslationsView;

        if (view == null) return;

        if (!_isSearchActive)
        {
            view.Filter = null;
        }
        else if (view.Filter == null)
        {
            view.Filter = FilterUserText;
        }
        else
        {
            view.Refresh();
        }
    }

    private bool FilterUserText(object o)
    {
        if (!_isSearchActive) return true;

        var item = (UserTextViewModel)o;

        return item.Key.Contains(_searchInput, StringComparison.InvariantCultureIgnoreCase) ||
               item.Value.Contains(_searchInput, StringComparison.InvariantCultureIgnoreCase);
    }




    private ICommand _clearSearchCommand;
    public ICommand ClearSearchCommand
    {
        get
        {
            return _clearSearchCommand ??
                   (_clearSearchCommand =
                    new DelegateCommand((param) =>
                    {
                        this.SearchInput = string.Empty;

                    }, (p) => !string.IsNullOrEmpty(this.SearchInput)));
        }
    }

    private async void OnRefreshRequired()
    {
        if (_isLoading) return;

        _isLoading = true;
        IsBusy = true;
        try
        {
            var result = await LoadDefinitions();
            TranslationsView = new ListCollectionView(result);
        }
        catch (Exception ex)
        {
            //ex.HandleError();//TODO: Needs to create properly error handling
        }

        _isLoading = false;
        IsBusy = false;
    }


    private async Task<IList> LoadDefinitions()
    {
        var translatioViewModels = await Task.Run(() => TranslationRepository.Instance.AllTranslationsCache
        .Select(model => new UserTextViewModel(model)).ToList());
        return translatioViewModels;
    }


}

XAML :

<UserControl x:Class="UCM.WFDesigner.Views.UserTextMainView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:model="clr-namespace:Cellebrite.Diagnostics.Model.Entities;assembly=Cellebrite.Diagnostics.Model"
         xmlns:System="clr-namespace:System;assembly=mscorlib"
         xmlns:converters1="clr-namespace:UCM.Infra.Converters;assembly=UCM.Infra"
         xmlns:core="clr-namespace:UCM.WFDesigner.Core"
         mc:Ignorable="d"
         d:DesignHeight="300"
         d:DesignWidth="300">


<DockPanel>
    <StackPanel Orientation="Horizontal"
                DockPanel.Dock="Top"
                HorizontalAlignment="Left">


        <DockPanel>

            <TextBlock Text="Search:"
                       DockPanel.Dock="Left"
                       VerticalAlignment="Center"
                       FontWeight="Bold"
                       Margin="0,0,5,0" />

            <Button Style="{StaticResource StyleButtonDeleteCommon}"
                    Height="20"
                    Width="20"
                    DockPanel.Dock="Right"
                    ToolTip="Clear Filter"
                    Command="{Binding ClearSearchCommand}" />

            <TextBox Text="{Binding SearchInput, UpdateSourceTrigger=PropertyChanged}"
                     Width="500"
                     VerticalContentAlignment="Center"
                     Margin="0,0,2,0"
                     FontSize="13" />

        </DockPanel>
    </StackPanel>
    <Grid>
        <DataGrid ItemsSource="{Binding Path=TranslationsView}"
                  AutoGenerateColumns="False"
                  SelectionMode="Single"
                  CanUserAddRows="True">
            <DataGrid.Columns>
              <!-- your columns definition is here-->
            </DataGrid.Columns>
        </DataGrid>
        <!-- your "busy indicator", that shows to user a message instead of stuck data grid-->
        <Border Visibility="{Binding IsBusy,Converter={converters1:BooleanToSomethingConverter TrueValue='Visible', FalseValue='Collapsed'}}"
                Background="#50000000">
            <TextBlock Foreground="White"
                       VerticalAlignment="Center"
                       HorizontalAlignment="Center"
                       Text="Loading. . ."
                       FontSize="16" />
        </Border>
    </Grid>
</DockPanel>

このパターンを使用すると、非常に単純な方法でデータ グリッドを操作でき、コードも非常に単純です。データ ソースを表すクラスの既定のコンストラクターを作成することを忘れないでください。

于 2016-06-09T07:51:53.200 に答える