2016-02-02 14 views
5

Daha eski XAML tabanlı UI çerçeveleri (WPF/SL) için bu soruna yönelik çözümler vardır, ancak Evrensel Windows Platformu'na kolayca uyarlanamazlar.Seçildiğinde genişleyen öğelere sahip bir Liste Kutusu oluşturun (Akordeon)

Varsayılan olarak yalnızca sınırlı ayrıntıları gösteren öğelerin bir listesini oluşturmaya çalışıyorum ve seçildiğinde, bazı verileri hızlı bir şekilde düzenlemek için genişletiyorum.
Windows 10 Mail uygulamasının yaptığı konuşmalara benzer olsa da, bu genişleyen bir davranış oluşturmanın bir yolunu bulamadım. Bir görüşmenin bir mesajı seçildiğinde, bu konuşmanın diğer mesajları aşağı doğru veya aşağı doğru kaydırılır.

Aşağıda, yalnızca ilk başta adını görüntülemek istediğim bir listenin bir örneği yer almaktadır. WPF

<ListBox ItemsSource="{x:Bind Persons}"> 
    <ListBox.ItemContainerStyle> 
     <Style TargetType="ListBoxItem"> 
      <Setter Property="HorizontalContentAlignment" Value="Stretch" /> 
     </Style> 
    </ListBox.ItemContainerStyle> 
    <ListBox.ItemTemplate> 
     <DataTemplate x:DataType="src:Person"> 
      <StackPanel HorizontalAlignment="Stretch" Width="Auto"> 
       <TextBlock Text="{x:Bind Path=Name, Mode=OneWay}" Margin="12, 15, 12, 0" FontSize="18.667" /> 
       <TextBox HorizontalAlignment="Stretch" Margin="12, 12, 12, 0" FontSize="18.667" Text="{x:Bind Path=Name, Mode=TwoWay}" /> 
       <TextBlock Text="Date of birth" Margin="12, 15, 12, 0" /> 
       <DatePicker Margin="12, 5, 12, 0" Date="{x:Bind Path=DateOfBirth, Mode=TwoWay}" /> 
       <TextBlock Text="Domicile" Margin="12, 15, 12, 0" /> 
       <TextBox Margin="12, 5, 12, 0" Text="{x:Bind Path=Domicile, Mode=OneWay}" /> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

, böyle bir davranışın tetikleyici Style.Triggers ile elde edilebilir ama artık mevcut değil.

Orijinal Kaynak Kodu GitHub

+0

UWP'de hala tetikleyicileriniz var ve bunu yapmak için düşünebildiğim hızlı ve basit bir şekilde, bunu saf XAML'de yapmanın birkaç yolu var. Bir tarz ToggleButton ile bir ItemTemplate yapın ve altında bir Panel collpased. Ardından panelin Görünürlüğünü ToggleButton'un IsChecked durumuna bağlayın ve bir Bool'u Görünürlük dönüştürücüsüne ekleyin, voila, bitti. –

cevap

0

ben UWP için genişletilebilir bir ListView kontrolünü yarattı - Eğer GitHub repo here bulabilirsiniz. Aslında, evrensel windows platformuyla çalışmaya adapte ettiğim WPF Expander'un portlanmış bir versiyonu.

Sorum ve sorumu burada bulabilirsiniz StackOverflow.

0

Chris Said gibi, genişleyen davranışı denetlemek için ViewModel'e bir özellik ekleyebiliriz, ancak bu ViewModel'i değiştirmeniz gerekir. Bunu yapmak istemezseniz, burada başka bir yaklaşım vardır:

Öncelikle, biri kısa bilgi görüntülemek için ve ayrıntıları görüntülemek için diğeri olmak üzere iki adet DataTemplate'a ihtiyacımız var. Örneğin:

<Page.Resources> 
    <!-- brief information template --> 
    <DataTemplate x:Key="ItemTemplate" x:DataType="src:Person"> 
     <StackPanel Width="Auto" HorizontalAlignment="Stretch"> 
      <TextBlock Margin="12, 15, 12, 0" 
         FontSize="18.667" 
         Text="{x:Bind Path=Name, Mode=OneWay}" /> 
      <TextBox Margin="12, 12, 12, 0" 
        HorizontalAlignment="Stretch" 
        FontSize="18.667" 
        Text="{x:Bind Path=Name, Mode=TwoWay}" /> 
     </StackPanel> 
    </DataTemplate> 
    <!-- details expand template --> 
    <DataTemplate x:Key="SelectedTemplate" x:DataType="src:Person"> 
     <StackPanel Width="Auto" HorizontalAlignment="Stretch"> 
      <TextBlock Margin="12, 15, 12, 0" 
         FontSize="18.667" 
         Text="{x:Bind Path=Name, Mode=OneWay}" /> 
      <TextBox Margin="12, 12, 12, 0" 
        HorizontalAlignment="Stretch" 
        FontSize="18.667" 
        Text="{x:Bind Path=Name, Mode=TwoWay}" /> 
      <StackPanel> 
       <TextBlock Margin="12, 15, 12, 0" Text="Date of birth" /> 
       <DatePicker Margin="12, 5, 12, 0" Date="{x:Bind Path=DateOfBirth, Mode=TwoWay}" /> 
       <TextBlock Margin="12, 15, 12, 0" Text="Domicile" /> 
       <TextBox Margin="12, 5, 12, 0" Text="{x:Bind Path=Domicile, Mode=OneWay}" /> 
      </StackPanel> 
     </StackPanel> 
    </DataTemplate> 
</Page.Resources> 

Sonra ListBox bilgi şablonu bilgilendirmek varsayılan ItemTemplate ayarlayın.

<ListBox ItemTemplate="{StaticResource ItemTemplate}" 
     ItemsSource="{x:Bind Persons}" 
     SelectionChanged="ListBox_SelectionChanged"> 
    <ListBox.ItemContainerStyle> 
     <Style TargetType="ListBoxItem"> 
      <Setter Property="HorizontalContentAlignment" Value="Stretch" /> 
     </Style> 
    </ListBox.ItemContainerStyle> 
</ListBox> 

Son olarak, SelectionChanged olaya ve seçilen ve seçilmemiş öğe için bu işleyici değişikliği ContentTemplate bir olay işleyicisi ekleyin.

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    var listBox = sender as ListBox; 
    //get unselected item 
    var unselectedPerson = e.RemovedItems.FirstOrDefault() as Person; 
    if (unselectedPerson != null) 
    { 
     //get unselected item container 
     var unselectedItem = listBox.ContainerFromItem(unselectedPerson) as ListBoxItem; 
     //set ContentTemplate 
     unselectedItem.ContentTemplate = (DataTemplate)this.Resources["ItemTemplate"]; 
    } 
    //get selected item container 
    var selectedItem = listBox.ContainerFromItem(listBox.SelectedItem) as ListBoxItem; 
    selectedItem.ContentTemplate = (DataTemplate)this.Resources["SelectedTemplate"]; 
} 
0

İşte bir çözüm kullanarak MVVM geçerli:

<ListBox ItemsSource="{Binding Items}" 
     SelectedItem="{Binding SelectedItem, Mode=TwoWay}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel> 
       <TextBlock Text="Title" /> 
       <TextBlock Text="Details" Visibility="{Binding IsSelected, Converter={StaticResource VisibilityConverter}}" /> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 
public class ViewModel : BindableBase 
{ 
    private Item _selectedItem; 


    public Item[] Items { get; } 

    public Item SelectedItem 
    { 
     get { return _selectedItem; } 
     set 
     { 
      if (_selectedItem != null) _selectedItem.IsSelected = false; 
      if (value != null) value.IsSelected = true; 
      SetProperty(ref _selectedItem, value); 
     } 
    } 
} 

public class Item : BindableBase 
{ 
    private bool _isSelected; 

    public bool IsSelected 
    { 
     get { return _isSelected; } 
     set { SetProperty(ref _isSelected, value); } 
    } 
} 

Başka bir çözüm yerine ListBoxItem.IsSelected görünürlük databind olabilir ListBox.ItemTemplate ait ListBoxItem.ControlTemplate düzenlemek olacaktır özellik, görsel durumlardan yararlanın.

1

İşte yapmak istediğiniz şey. ListView tarafından doğal olarak belirlenen ListViewItem.IsSelected özelliğini kullanmak istiyorsunuz. Ardından, bu değere göre değişime tepki vermek ve ayrıntılarınızı açığa çıkaran veya gizleyen bir görsel durum belirlemek istiyorsunuz.

Bunun gibi

: Yeterince komik

class MyModel 
{ 
    public bool IsSelected { get; set; } 
} 

class MyList : Windows.UI.Xaml.Controls.ListView 
{ 
    protected override void PrepareContainerForItemOverride(DependencyObject element, object item) 
    { 
     var model = item as MyModel; 
     var listViewItem = element as Windows.UI.Xaml.Controls.ListViewItem; 

     var binding = new Windows.UI.Xaml.Data.Binding 
     { 
      Source = model, 
      Mode = Windows.UI.Xaml.Data.BindingMode.TwoWay, 
      Path = new PropertyPath(nameof(model.IsSelected)), 
     }; 
     listViewItem.SetBinding(Windows.UI.Xaml.Controls.ListViewItem.IsSelectedProperty, binding); 
     base.PrepareContainerForItemOverride(element, item); 
    } 
} 

ama bu kod biraz değişken büyüklükte sargı ızgaraları için kullanılan kodun dayanmaktadır. Orijinal makaleyi buradan okuyabilirsiniz. http://blog.jerrynixon.com/2012/08/windows-8-beauty-tip-using.html

Visual Devletleri hakkında daha fazla bilgi edinmek istiyorsanız

, benim aynı konudaki yazdığı blog makalesinde üzerinde okuyabilir. Böyle

http://blog.jerrynixon.com/2013/11/windows-81-how-to-use-visual-states-in.html

şey: Windows uygulamalarında XAML davranışlar hakkında daha fazla bilgi edinmek isterseniz

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 

    <Interactivity:Interaction.Behaviors> 
     <Core:DataTriggerBehavior Binding="{Binding IsSelected}" Value="True"> 
      <Core:GoToStateAction StateName="BigVisualState"/> 
     </Core:DataTriggerBehavior> 
     <Core:DataTriggerBehavior Binding="{Binding IsSelected}" Value="False"> 
      <Core:GoToStateAction StateName="LittleVisualState"/> 
     </Core:DataTriggerBehavior> 
    </Interactivity:Interaction.Behaviors> 

    <VisualStateManager.VisualStateGroups> 
     <VisualStateGroup x:Name="VisualStateGroup"> 
      <VisualState x:Name="BigVisualState"/> 
      <VisualState x:Name="LittleVisualState"/> 
     </VisualStateGroup> 
    </VisualStateManager.VisualStateGroups> 

</Grid> 

, ne konuda yazdığı makaleyi okuyabilirsiniz.

Ben de Hoşunuza gidebilecek bir ders kaydedildi http://blog.jerrynixon.com/2013/10/everything-i-know-about-behaviors-in.html

. https://mva.microsoft.com/en-US/training-courses/designing-your-xaml-ui-with-blend-jump-start-8260?l=p2dPykKy_5104984382

umarım bu yardımcı olur.

Şansın en iyisi!

İlgili konular