2

わかりました、2 つのデータ テンプレートを作成したコンテナーがあります。基本的に、1 つのテンプレートは 5 つのテキスト ボックスとそれにバインドされたオブジェクト データを表示し、もう 1 つのテンプレートはその特定のオブジェクトを追加するためのボタンを表示します。私は DataTemplateSelector をサブクラス化し、それは機能しますが、レコードをナビゲートすると、セレクターが再び呼び出されることはありません。

では、コンテナがそのテンプレートを再選択するにはどうすればよいでしょうか。コンテナーは StackPanel であり、私は既に UpdateVisuals、InvalidateVisuals、InvalidateArrange、および ApplyTemplate を試しました。

XAML コード

<DataTemplate x:Key="advisorTemplate">
        <StackPanel Orientation="Vertical" Margin="2,2,2,2" HorizontalAlignment="Stretch" VerticalAlignment="Top">
            <StackPanel Orientation="Horizontal" Margin="2,2,2,2" HorizontalAlignment="Center">
                <extToolkit:WatermarkTextBox Name="txtAcadAdv" Watermark="Acad Adv" Width="125" Margin="2" Text="{Binding Path=Adv.AcadAdv}"/>
                <extToolkit:WatermarkTextBox Name="txtProgAdv" Watermark="Prog Adv" Width="125" Margin="2" Text="{Binding Path=Adv.ProgAdv}"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="2,2,2,2" HorizontalAlignment="Center">
                <extToolkit:WatermarkTextBox Name="txtPortAdv" Watermark="Port Adv" Width="125" Margin="2" Text="{Binding Path=Adv.PortAdv}"/>
                <extToolkit:WatermarkTextBox Name="txtEleTws" Watermark="Ele Tws" Width="125" Margin="2" Text="{Binding Path=Adv.EleTws}"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="2,2,2,2" HorizontalAlignment="Center">
                <extToolkit:WatermarkTextBox Name="txtMatTws" Watermark="Mat Tws" Width="125" Margin="2" Text="{Binding Path=Adv.MatTws}"/>
            </StackPanel>
        </StackPanel>
    </DataTemplate>
    <DataTemplate x:Key="addAdvisor">
        <Button HorizontalAlignment="Center" VerticalAlignment="Center" Margin="2" Name="btnAddAdvisor" Click="ButtonClick" Content="Add Advisor"/>
    </DataTemplate> 

グループボックスの変更内容の初期化

grpAdv.ContentTemplateSelector = _advisorSelector;

そして最後にセレクターコード

private readonly StudentWin _win;

    public  AdvisorDataTemplateSelector(StudentWin win)
    {
        _win = win;
    }

    public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
    {
        var sp = item as StackPanel;
        var adv = sp.DataContext as Advisor;


        if (adv == null)
            return _win.FindResource("addAdvisor") as DataTemplate;

        return _win.FindResource("advisorTemplate") as DataTemplate;
    }

そして、これが私のナビゲーションコードのスニペットです

case "btnNext":
                    {
                        if(_view.CurrentPosition < _view.Count - 1)
                        {
                            CheckForUnusedReferences(_view.GetItemAt(_view.CurrentPosition) as Student);
                            _view.MoveCurrentToNext();
                            CheckForNullReferences(_view.CurrentPosition);
                            grpAdv.ApplyTemplate();
                        }
                    }

追加の 2 つのメソッドは、生徒の関係が null であるかどうかを確認することです。関係が作成され、データ コンテキストに追加されます。それ以外の場合、Entity Framework は変更を保存しません。上記のデータ テンプレートは基本的に、新しい学生を作成しようとしたときに学生 ID がないという問題を解決するのに役立ちます。

4

1 に答える 1

2

次の方法を使用して、DataTemplateSelectorの再適用を強制しました。

ObservableCollectionから派生し、NotifyCollectionChangedAction.Resetを使用してNotifyCollectionChangedEventArgsを発生させるメソッドを追加します。

public class MyThingCollection : ObservableCollection<MyThing>
{
    public void RaiseResetCollection()
    {
        OnCollectionChanged(new 
            NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }
}

ビューモデルはこのタイプのインスタンスを公開し、ItemsControlはそれにバインドします。

public class MyViewModel : ... (view model base)
{
    public MyThingCollection Items{get; private set;}
}

<ItemsControl
     ItemsSource="{Binding Items}"
     ItemsTemplateSelector="{StaticResource MyTemplateSelector}"
     ...

DataTemplateSelectorを再適用する必要がある場合は、コレクションでRaiseResetCollectionを呼び出します。

私は通常、このようなDataTemplateSelectorを使用します

public class MyTemplateSelector : DataTemplateSelector
{
    public DataTemplate Template1 { get; set; }
    public DataTemplate Template2 { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        ... return Template1 or Template2 depending on item
    }
    ...
}

<DataTemplate x:Key="MyTemplate1" DataType="{x:Type MyType1}">
    ...
</DateTemplate>

<DataTemplate x:Key="MyTemplate2" DataType="{x:Type MyType2}">
    ...
</DateTemplate>

<local:MyTemplateSelector 
    x:Key="MyTemplateSelector" 
    Template1="{StaticResource MyTemplate1}"
    Template2="{StaticResource MyTemplate2}"
/>
于 2012-05-26T19:48:32.957 に答える