2016-06-30 8 views
0

Ich erstelle tatsächlich ein UserControl für eine benutzerdefinierte ListView. Was ich versuche zu erreichen, ist dasselbe wie dieser Beitrag: Hide or Show stackpanel of ListViewItem with VisualStateManager. Ich habe den Code bereits implementiert und es funktioniert, aber jetzt möchte ich es "generischer" machen, also habe ich ein Benutzersteuerelement erstellt.Benutzerdefinierte UWP/XAML-Eigenschaft, die Steuerelemente "hosten" kann

Meine Kontrolle ist in zwei Raster unterteilt. Das obere Gitter und das ausgeblendete verborgene Gitter.

Und ich möchte, dass meine Benutzersteuerung wie folgt verwenden:

<controls:ExpandableListView ItemsSource="{Binding ConnectedObjects}"> 
    <controls:ExpandableListView.Header> 
     <TextBlock Text="Hello World!" /> 
    </controls:ExpandableListView.Header> 
    <controls:ExpandableListView.ExpandedContent> 
     <Button Content="test 2" /> 
    </controls:ExpandableListView.ExpandedContent> 
</controls:ExpandableListView> 

Die Header Eigenschaft ist der Inhalt, die im oberen Raster platziert werden soll, und die ExpandedContent ist der Inhalt in dem kollabierten Raster platziert.

In meiner Benutzerkontrolle ich habe:

<ListView x:Name="LIST" SelectionChanged="LIST_SelectionChanged" ItemsSource="{Binding ItemsSource}"> 

    <!-- Item container style --> 
    <ListView.ItemContainerStyle> 
     <Style TargetType="ListViewItem"> 
      <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 
     </Style> 
    </ListView.ItemContainerStyle> 

    <!-- Item template --> 
    <ListView.ItemTemplate> 
     <DataTemplate> 
      <Grid> 
       <Grid.RowDefinitions> 
        <RowDefinition /> 
        <RowDefinition /> 
       </Grid.RowDefinitions> 

       <Grid x:Name="GRID_1" Grid.Row="0"> 
        <ContentPresenter Content="{Binding Path=Header}" /> 
       </Grid> 

       <Grid x:Name="GRID_2" Grid.Row="1" Visibility="Collapsed"> 
        <ContentPresenter Content="{Binding Path=ExpandedContent}" /> 
       </Grid> 

       <VisualStateManager.VisualStateGroups> 
        <VisualStateGroup x:Name="CommonStates"> 
         <VisualState x:Name="Normal"></VisualState> 
         <VisualState x:Name="Selected"> 
          <VisualState.Setters> 
           <Setter Target="GRID_2.Visibility" Value="Visible"></Setter> 
          </VisualState.Setters> 
         </VisualState> 
        </VisualStateGroup> 
       </VisualStateManager.VisualStateGroups> 

      </Grid> 
     </DataTemplate> 
    </ListView.ItemTemplate> 
</ListView> 

Dort wird der Code hinter der Steuer Benutzer

public sealed partial class ExpandableListView : UserControl 
{ 
    private static readonly DependencyProperty ItemsSourceProperty = 
     DependencyProperty.Register(
      "ItemsSource", 
      typeof(IEnumerable), 
      typeof(ExpandableListView), 
      new PropertyMetadata(null)); 

    public static readonly DependencyProperty HeaderContentProperty = 
     DependencyProperty.Register(
      "Header", 
      typeof(Object), 
      typeof(ExpandableListView), 
      new PropertyMetadata(null)); 

    public static readonly DependencyProperty ExpandedContentProperty = 
     DependencyProperty.Register(
      "ExpandedContent", 
      typeof(Object), 
      typeof(ExpandableListView), 
      new PropertyMetadata(null)); 

    public IEnumerable ItemsSource 
    { 
     get { return this.GetValue(ItemsSourceProperty) as IEnumerable; } 
     set { this.SetValue(ItemsSourceProperty, value); } 
    } 

    public Object Header 
    { 
     get { return (Object)this.GetValue(HeaderContentProperty); } 
     set { this.SetValue(HeaderContentProperty, value); } 
    } 

    public Object ExpandedContent 
    { 
     get { return (Object)this.GetValue(ExpandedContentProperty); } 
     set { this.SetValue(ExpandedContentProperty, value); } 
    } 

    public ExpandableListView() 
    { 
     this.InitializeComponent(); 
     this.LIST.DataContext = this; 
    } 

    private void LIST_SelectionChanged(Object sender, SelectionChangedEventArgs e) 
    { 
    } 

    private void SetInEditMode() 
    { 
     VisualStateManager.GoToState(this, "Selected", true); 
    } 

    private void SetInViewMode() 
    { 
     VisualStateManager.GoToState(this, "Normal", true); 
    } 
} 
+0

Was ist Ihre Frage? –

+0

Meine Frage ist, wie kann ich den Inhalt zwischen meinen '' und '' in meinem ListView anzeigen. Ich verwende das ItemTemplate, um die Elementzelle zu formatieren, und ich habe 'Header' und' ExpandedContent', die 'FrameworkElements' sind. Aber so scheint es nicht zu funktionieren. Ich habe es auch mit einem ContentControl versucht, aber ohne Erfolg. – Eastrall

Antwort

0
<Grid x:Name="GRID_2" Grid.Row="1" Visibility="Collapsed"> 
     <ContentPresenter Content="{Binding MyUsersContent }"/> 
    </Grid> 

In Ihrer Kontrolle CS Datei

public class YourControl{ 

    public Object MyUsersContent 
    { 
     get { return (Object)GetValue(MyUsersContentProperty); } 
     set { SetValue(MyUsersContentProperty, value); } 
    } 

    public static readonly DependencyProperty MyUsersContentProperty = 
        DependencyProperty.Register("MyUsersContent", 
         typeof(Object), typeof(YoutControl), new PropertyMetadata()); 
} 

Dieses ist wahrscheinlich der einfachste Weg zu tun es. Dies ist der Grund, warum wir Ihren Code sehen müssen. Weil es einen Unterschied macht, wie Sie diese Funktion implementieren. Wenn Sie Probleme mit der Bindung haben, können Sie Ihr Steuerelement in der OnApplyTemplate-Funktion abrufen und manuell einpumpen.

Bevor Sie fortfahren, würde ich dieses Tutorial sehr empfehlen. Es wird Ihnen eine Vorstellung davon geben, wie dies und viele andere Probleme, mit denen Sie konfrontiert werden, gelöst werden sollten.

How to create a Custom Control in WPF

+0

Vielen Dank für Ihre Antwort, ich habe meinen ursprünglichen Beitrag bearbeitet den Code hinter dem Benutzersteuerelement hinzugefügt. Auch versucht, '' und es funktioniert leider nicht. – Eastrall

+0

Deshalb habe ich gesagt, dass der Rest des Codes zählt. Anstatt templated Eltern zu verwenden binden Sie einfach direkt an es. –

1

Ich glaube, Sie content-Attribut hinzufügen müssen angeben, welche Eigenschaft als Inhalt verwendet werden. Beispiel:

[ContentProperty("ExpandedContent")] 
public sealed partial class ExpandableListView : UserControl 
{ 
... 
    public static readonly DependencyProperty ExpandedContentProperty = 
     DependencyProperty.Register(
      "ExpandedContent", 
      typeof(Object), 
      typeof(ExpandableListView), 
      new PropertyMetadata(null)); 
... 
    public Object ExpandedContent 
    { 
     get { return (Object)this.GetValue(ExpandedContentProperty); } 
     set { this.SetValue(ExpandedContentProperty, value); } 
    } 

... 
} 

Auch ziehe ich nemeof() in Abhängigkeitseigenschaft Erklärung zu verwenden. Es macht Code sicherer Refactoring und Umbenennung:

public static readonly DependencyProperty ExpandedContentProperty = 
    DependencyProperty.Register(
     nameof(ExpandedContent), 
     typeof(Object), 
     typeof(ExpandableListView), 
     new PropertyMetadata(null));