2016-02-02 7 views
5

पुराने XAML आधारित UI ढांचे (WPF/SL) के लिए इस समस्या का समाधान है लेकिन वे यूनिवर्सल विंडोज प्लेटफ़ॉर्म के लिए आसानी से अनुकूल नहीं हैं।चयनित वस्तुओं के साथ एक सूची बॉक्स बनाएं (Accordion)

मैं उन आइटम्स की एक सूची बनाने की कोशिश कर रहा हूं जो डिफ़ॉल्ट स्थिति में केवल सीमित विवरण दिखाते हैं और विस्तार करते समय विस्तारित होते हैं, कुछ डेटा को त्वरित रूप से संपादित करने के लिए।
मुझे उस विस्तारित व्यवहार को बनाने का कोई तरीका नहीं मिला है, हालांकि यह बातचीत के साथ विंडोज 10 मेल ऐप के समान है। जब किसी वार्तालाप का संदेश चुना जाता है, तो उस वार्तालाप के अन्य संदेश ड्रॉप डाउन या स्लाइड डाउन करते हैं।

नीचे एक सूची का एक उदाहरण है जहां मैं केवल पहले नाम प्रदर्शित करना चाहता हूं।

<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> 

WPF में, इस तरह के व्यवहार चलाता Style.Triggers साथ प्राप्त किया जा सकता है, लेकिन वे अब उपलब्ध नहीं हैं।

मूल स्रोत कोड GitHub

+0

आपके पास अभी भी यूडब्ल्यूपी में आपके लिए ट्रिगर्स उपलब्ध हैं, और शुद्ध XAML में ऐसा करने के कई तरीके हैं, एक त्वरित और सरल तरीका मैं ऐसा करने के बारे में सोच सकता हूं। एक स्टाइल टॉगल बटन के साथ एक आइटम टेम्पलेट बनाएं और इसके नीचे एक पैनल ध्वस्त हो। फिर पैनल की दृश्यता को टॉगल बटन के Ischecked स्थिति में बाध्य करें और दृश्यता कनवर्टर, voila, करने के लिए एक बूल जोड़ें। –

उत्तर

0

पर मैं UWP के लिए एक विस्तार योग्य ListView नियंत्रण बनाया - आप इसे GitHub रेपो में here पा सकते हैं। यह वास्तव में WPF Expander का एक पोर्ट संस्करण है जिसे मैंने सार्वभौमिक विंडोज प्लेटफ़ॉर्म के साथ काम करने के लिए अनुकूलित किया है।

आप मेरा प्रश्न और उत्तर यहां देख सकते हैं StackOverflow पर।

0

क्रिस सैद की तरह, हम विस्तार व्यवहार को नियंत्रित करने के लिए व्यूमोडेल में एक संपत्ति जोड़ सकते हैं, लेकिन इसे व्यूमोडेल को बदलने की आवश्यकता है। यदि आप ऐसा नहीं करना चाहते हैं, तो यहां एक और दृष्टिकोण है:

सबसे पहले, हमें दो DataTemplate की आवश्यकता है, एक संक्षिप्त जानकारी प्रदर्शित करने के लिए और दूसरा विवरण प्रदर्शित करने के लिए। उदाहरण के लिए:

<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> 

फिर ListBox में जानकारी टेम्पलेट संक्षिप्त डिफ़ॉल्ट ItemTemplate निर्धारित किया है।

<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> 

अंत में, SelectionChanged घटना के लिए और चयनित और अचयनित किया गया आइटम के लिए इस हैंडलर परिवर्तन ContentTemplate में एक ईवेंट हैंडलर जोड़ें।

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

यहाँ का उपयोग कर MVVM एक समाधान है:

<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); } 
    } 
} 

एक अन्य समाधान ListBox.ItemTemplate है, जहां आप ListBoxItem.IsSelected के लिए दृश्यता DataBind कर सकते हैं के बजाय ListBoxItem.ControlTemplate संपादित करने के लिए किया जाएगा संपत्ति, दृश्य राज्यों का लाभ ले लो।

1

यहां आप क्या करना चाहते हैं। आप ListViewItem.Is चयनित संपत्ति का उपयोग करना चाहते हैं जो सूची दृश्य द्वारा मूल रूप से सेट किया गया है। फिर, आप उस मूल्य परिवर्तन पर प्रतिक्रिया देना चाहते हैं और एक दृश्य स्थिति सेट करना चाहते हैं जो आपके विवरणों को प्रकट या छुपाता है।

इस तरह

:

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); 
    } 
} 

काफी अजीब बात है, लेकिन इस कोड को कुछ हद तक चर आकार चादर ग्रिड के लिए इस्तेमाल किया कोड पर आधारित है। आप यहां मूल लेख पढ़ सकते हैं।

http://blog.jerrynixon.com/2012/08/windows-8-beauty-tip-using.html

आप दृश्य स्टेट्स के बारे में अधिक जानना चाहते हैं, तो आप ब्लॉग लेख मैं एक ही विषय पर लिखा था पर पढ़कर सुना सकता है।

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

कुछ इस तरह:

<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> 

आप Windows क्षुधा में XAML व्यवहार के बारे में अधिक जानने के लिए चाहते हैं, तो आप लेख मैं विषय पर लिखा था पढ़ सकते हैं।

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

मुझे आशा है कि इस मदद करता है।

शुभकामनाएँ!

संबंधित मुद्दे