あなたは多くのコードを共有していなかったので、 。アイデア:MyCustomControl
はアイテムをホストしており、そのためにListView
がControlTemplate
で使用されています。デフォルトGridView
はControlTemplate
に直接含まれているが、それはMyCustomControl.MyView
カスタムコントロールを経由して、それを変更することが可能です:
:
コントロールテンプレート
public class MyCustomControl : ItemsControl
{
static MyCustomControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new FrameworkPropertyMetadata(typeof(MyCustomControl)));
}
public ViewBase MyView
{
get { return (ViewBase)GetValue(MyViewProperty); }
set { SetValue(MyViewProperty, value); }
}
public static readonly DependencyProperty MyViewProperty =
DependencyProperty.Register("MyView", typeof(ViewBase), typeof(MyCustomControl), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnMyViewChanged)));
private static void OnMyViewChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((MyCustomControl)d).HasCustomView = e.NewValue != null;
}
// readonly property to support the Trigger in the ControlTemplate in order to exchange the ListView.View
public bool HasCustomView
{
get { return (bool)GetValue(HasCustomViewProperty); }
private set { SetValue(HasCustomViewPropertyKey, value); }
}
private static readonly DependencyPropertyKey HasCustomViewPropertyKey =
DependencyProperty.RegisterReadOnly("HasCustomView", typeof(bool), typeof(MyCustomControl), new PropertyMetadata(false));
public static readonly DependencyProperty HasCustomViewProperty = HasCustomViewPropertyKey.DependencyProperty;
}
(デフォルトのGridViewコントロールおよび交換のためのトリガーを注意してください)
<Style TargetType="{x:Type local:MyCustomControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyCustomControl}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ListView x:Name="PART_ListView"
ItemsSource="{Binding Items,RelativeSource={RelativeSource TemplatedParent}}">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="DEF"/>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="HasCustomView" Value="True">
<Setter TargetName="PART_ListView" Property="View" Value="{Binding MyView,RelativeSource={RelativeSource TemplatedParent}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
使用法:
<local:MyCustomControl>
<!--uses default view-->
<TextBlock Text="Item 1"/>
<TextBlock Text="Item 2"/>
</local:MyCustomControl>
<local:MyCustomControl>
<!--uses custom view-->
<local:MyCustomControl.MyView>
<GridView>
<GridView.Columns>
<GridViewColumn Header="ABC"/>
</GridView.Columns>
</GridView>
</local:MyCustomControl.MyView>
<TextBlock Text="Item 1"/>
<TextBlock Text="Item 2"/>
</local:MyCustomControl>
不明な点が残っているかどうか自由にお尋ねください。コメントしたように、私はあなたのDataTemplate
アイデアをこのすべてのものに適用する方法を知らない。
編集:
は、以下のいくつかのデータとDataTemplate
Sならびにそれらの可能な使用法を定義するリソースセクションを有する例です。私はすでに私の最初の編集で説明したように、私はまさにこれを解決するだろう
:コメントMCVEをターゲット
<StackPanel>
<StackPanel.Resources>
<x:Array x:Key="Items1" Type="{x:Type sys:Int32}">
<sys:Int32>1</sys:Int32>
<sys:Int32>2</sys:Int32>
<sys:Int32>3</sys:Int32>
<sys:Int32>4</sys:Int32>
</x:Array>
<x:Array x:Key="Items2" Type="{x:Type sys:Int32}">
<sys:Int32>5</sys:Int32>
<sys:Int32>4</sys:Int32>
<sys:Int32>6</sys:Int32>
<sys:Int32>7</sys:Int32>
</x:Array>
<CollectionViewSource x:Key="ItemsSource1" Source="{StaticResource Items1}"/>
<CollectionViewSource x:Key="ItemsSource2" Source="{StaticResource Items2}"/>
<DataTemplate x:Key="IntegerListTemplate1">
<local:MyCustomControl ItemsSource="{Binding}">
<!--uses default view-->
</local:MyCustomControl>
</DataTemplate>
<DataTemplate x:Key="IntegerListTemplate2">
<local:MyCustomControl ItemsSource="{Binding}">
<!--uses custom view-->
<local:MyCustomControl.MyView>
<GridView>
<GridView.Columns>
<GridViewColumn Header="ABC"/>
</GridView.Columns>
</GridView>
</local:MyCustomControl.MyView>
</local:MyCustomControl>
</DataTemplate>
</StackPanel.Resources>
<!--the default view-->
<ContentControl ContentTemplate="{StaticResource IntegerListTemplate1}" Content="{Binding Source={StaticResource ItemsSource1}}"/>
<Separator Margin="3"/>
<!--same items other view-->
<ContentControl ContentTemplate="{StaticResource IntegerListTemplate2}" Content="{Binding Source={StaticResource ItemsSource1}}"/>
<Separator Margin="3"/>
<!--different items same view as second one, no complaints about reusing-->
<ContentControl ContentTemplate="{StaticResource IntegerListTemplate2}" Content="{Binding Source={StaticResource ItemsSource2}}"/>
</StackPanel>
編集2、。コントロールをスタイルに変換するのではなく、DataTemplate
にします。
MainWindow.xamlに置き換えます。他の出現箇所と
<!-- old -->
<myctrls:MyControl Grid.Row="0" Grid.Column="0" Style="{StaticResource AddressStyle}" ItemsSource="{Binding Addresses}"/>
<!-- new -->
<ContentControl Grid.Row="0" Grid.Column="0" ContentTemplate="{StaticResource AddressTemplate}" Content="{Binding Addresses}"/>
同じ。
In MyControlStyles。xaml(またはDataTemplate
の使用を示す名前の変更されたファイル)を使用して、GridView
リソースとStyle
をmyctrls:MyControl
にマージしてDataTemplate
にします。
旧:
<GridView x:Key="AddressGridView" x:Shared="False">
<GridViewColumn Header="City" Width="Auto" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding City}" HorizontalAlignment="Left"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Country" Width="Auto" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Country}" HorizontalAlignment="Left"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
<Style x:Key="AddressStyle" TargetType="{x:Type myctrls:MyControl}">
<Setter Property="SuggestionsView" Value="{DynamicResource AddressGridView}"/>
</Style>
新:ProductsStyle
ため
<DataTemplate x:Key="AddressTemplate">
<!-- the base control -->
<myctrls:MyControl ItemsSource="{Binding}">
<!-- this was previously assigned by AddressStyle -->
<myctrls:MyControl.SuggestionsView>
<!-- this was previously the AddressGridView -->
<!-- Same as before, only removed the x:Key and x:Shared -->
<GridView>
<GridViewColumn Header="City" Width="Auto" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding City}" HorizontalAlignment="Left"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Country" Width="Auto" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Country}" HorizontalAlignment="Left"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</myctrls:MyControl.SuggestionsView>
</myctrls:MyControl>
</DataTemplate>
同じ手順。
ContentControl
ワイヤアップアプローチが嫌いなら、AddressListViewModel
のようなコレクションをホストする追加のビューモデルを作成することを検討してください。これにより、リソースキーではなくDataType
でDataTemplate
を処理し、明示的に使用する場合はContentControl
になります。
私はあなたがある時点で少し外れていると感じます。 ['ListView.View'](https://msdn.microsoft.com/en-us/library/system.windows.controls.listview.view(v = vs.110).aspx)の型は' ViewBase'なので外部からこの部分をCustomControlに渡す場合は、この型のプロパティが必要です。たぶん、いくつかのサンプルコードは、この全部で 'DataTemplate'をどこにしたいのかを理解するのに役立ちます。 – grek40
はい、そうです。現時点では、私はViewBase型のDependencyPropertyを持っています。 ResourceDictionaryには、そのプロパティのリソースとそのリソースを割り当てるセッターのスタイルがあります。上で述べたように、RunTimeでこれらのリソースを使用できるようにするには、x:Shared = falseを設定する必要がありましたが、設計時に問題が発生します。 GridViewの定義を含むDataTemplateを受け入れるようにコントロールを変更する必要があります。コントロールは、DataTemplateのインスタンスを作成する必要があります。私の質問は、DataTemplateからインスタンスを作成する方法です。 – E812
リストビューのitemsourceとItemtemplateをバインドするだけの理由はありませんか? – MikeT