2016-10-30 10 views
3

UWPでを選択して、選択時のビューを変更します。だから私は、ListViewItemのいくつかの要素のVisibilityプロパティを変更する必要があります。ListViewItemのDataTemplateでIsSelectedプロパティをバインドする方法

私はListViewItemのカスタムスタイルを作成し、このようなIsSelectedプロパティをバインディングでこれを行うにはいくつかの方法が見つかりました:

<Style x:Key="VehicleListViewItemStyle" TargetType="ListViewItem" > 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="ListViewItem"> 
         <Grid Background="Gray" Margin="1"> 
          <Border Margin="2" Padding="10" Background="Gray" > 
           <StackPanel> 
            <ContentPresenter x:Name="Presenter1" /> 
            <StackPanel Orientation="Horizontal" Background="Transparent" Margin="-10,0,-9,-9" VerticalAlignment="Center" x:Name="infoPanel" 
             Visibility="{Binding IsSelected, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}}"> 
             <TextBlock Text="{Binding DeviceID}/>                   </StackPanel> 
           </StackPanel> 
          </Border> 
          <Border BorderThickness="1" BorderBrush="Orange" Visibility="{Binding IsSelected, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}}"/> 
         </Grid> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 

その良い作業が、この方法で私はDeviceIDテキストをバインド傾けます。

<DataTemplate x:Key="monitoringListViewItem" x:Name="item"> 
      <Grid Background="Gray" Margin="1" Width="300" > 
       <StackPanel> 
        <ContentPresenter x:Name="Presenter"/> 
        <StackPanel Orientation="Horizontal"> 
         <Image Source="/Assets/14th_crane_stop.png" Height="50" Width="50" Stretch="Uniform"/> 
         <StackPanel Orientation="Vertical" Margin="25,0,0,0 " 
            Visibility="{Binding IsSelected, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}}" 
            > 
          <TextBlock Text="{Binding DeviceID}" Style="{StaticResource VehicleTextStyle}"/> 
          <TextBlock Text="{Binding Mark}" Style="{StaticResource VehicleTextStyle}"/> 
         </StackPanel> 
        </StackPanel> 
       </StackPanel > 
      </Grid> 
     </DataTemplate> 

は、今私はテキストを正確にバインドすることができますが、IsSelectedプロパティをバインドカント:

もう一つの方法は、このようなDataTemplateを作成しています。私は別のモードでこれをやろうとしましたが、DataTemplate内でTemplatedParentキーを使用できないため、まだ動作しません。私は最初の方法でテキストを結合して、私はそれをどのように行うことができます-CAN

は、だから私はいくつかの答えがありますか? - 第2の方法でIsSelectedプロパティをバインドする方法はありますか?

+0

あなたのListViewコントロールは、単一選択または複数選択を持っていますか? –

+0

@Decade Moon、Multiple – selezen88

答えて

2

ListViewItemテンプレートを変更することはお勧めできません。これは、提供されるすべての鐘や笛(選択の外観、チェックする能力など)を失うためです。

Mode=TemplatedParentを2番目のスニペットで使用すると、そのコンテキストのテンプレート化された親はListViewItem(プレゼンターの親)ではなくListViewItemPresenterであるため、機能しません。

あなたがしようとしているのは、リスト項目が選択されているときに追加情報を表示することです。

単一選択

C#クラス

public class NotifyPropertyChangedBase : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected void OnPropertyChanged([CallerMemberName] string propertyName = "") 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    protected bool SetProperty<T>(ref T property, T value, [CallerMemberName] string propertyName = "") 
    { 
     if (EqualityComparer<T>.Default.Equals(property, value)) 
     { 
      return false; 
     } 

     property = value; 
     OnPropertyChanged(propertyName); 
     return true; 
    } 
} 

public class Item : NotifyPropertyChangedBase 
{ 
    private string text; 
    public string Text 
    { 
     get { return text; } 
     set { SetProperty(ref text, value); } 
    } 

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

public class MainPageViewModel : NotifyPropertyChangedBase 
{ 
    public List<Item> Items { get; set; } 

    private Item selectedItem; 
    public Item SelectedItem 
    { 
     get { return selectedItem; } 
     set 
     { 
      if (selectedItem != value) 
      { 
       if (selectedItem != null) 
       { 
        selectedItem.IsSelected = false; 
       } 

       SetProperty(ref selectedItem, value); 

       if (selectedItem != null) 
       { 
        selectedItem.IsSelected = true; 
       } 
      } 
     } 
    } 

    public MainPageViewModel() 
    { 
     Items = new List<Item>() 
     { 
      new Item() { Text = "Apple" }, 
      new Item() { Text = "Banana" }, 
     }; 
    } 
} 

MainPage.xamlを

<ListView ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}"> 
    <ListView.ItemContainerStyle> 
     <Style TargetType="ListViewItem"> 
      <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 
     </Style> 
    </ListView.ItemContainerStyle> 
    <ListView.ItemTemplate> 
     <DataTemplate x:DataType="local:Item"> 
      <Grid> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition/> 
        <ColumnDefinition Width="Auto"/> 
       </Grid.ColumnDefinitions> 

       <TextBlock Text="{Binding Text}"/> 

       <!-- x:Bind doesn't require visibility converter if min SDK is targeting Anniversary update --> 
       <TextBlock Text="I'm selected!" Grid.Column="1" Visibility="{x:Bind IsSelected, Mode=OneWay}"/> 
      </Grid> 
     </DataTemplate> 
    </ListView.ItemTemplate> 
</ListView> 

MainPage.xaml.cs

public sealed partial class MainPage : Page 
{ 
    public MainPage() 
    { 
     this.InitializeComponent(); 
     DataContext = new MainPageViewModel(); 
    } 
} 

Screenshot

複数選択単一選択としてではなく、次のように変更と同じ

MainPageViewModel

public class MainPageViewModel : NotifyPropertyChangedBase 
{ 
    public List<Item> Items { get; set; } 

    public MainPageViewModel() 
    { 
     Items = new List<Item>() 
     { 
      new Item() { Text = "Apple" }, 
      new Item() { Text = "Banana" }, 
     }; 
    } 

    public void SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     foreach (Item item in e.RemovedItems) 
     { 
      item.IsSelected = false; 
     } 

     foreach (Item item in e.AddedItems) 
     { 
      item.IsSelected = true; 
     } 
    } 
} 

メインページ。XAML

<ListView ItemsSource="{Binding Items}" SelectionChanged="{x:Bind ViewModel.SelectionChanged}" SelectionMode="Extended"> 
    <ListView.ItemContainerStyle> 
     <Style TargetType="ListViewItem"> 
      <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 
     </Style> 
    </ListView.ItemContainerStyle> 
    <ListView.ItemTemplate> 
     <DataTemplate x:DataType="local:Item"> 
      <Grid> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition/> 
        <ColumnDefinition Width="Auto"/> 
       </Grid.ColumnDefinitions> 

       <TextBlock Text="{Binding Text}"/> 
       <TextBlock Text="I'm selected!" Grid.Column="1" Visibility="{x:Bind IsSelected, Mode=OneWay}"/> 
      </Grid> 
     </DataTemplate> 
    </ListView.ItemTemplate> 
</ListView> 

MainPage.xaml.cs

public sealed partial class MainPage : Page 
{ 
    public MainPage() 
    { 
     this.InitializeComponent(); 
     DataContext = new MainPageViewModel(); 
    } 

    public MainPageViewModel ViewModel => (MainPageViewModel)DataContext; 
} 

Screenshot

+0

私は複数の選択を使用しています...わかりませんが、このソリューションでは、すべての選択したアイテムはVisiblePropertyを変更しますか? – selezen88

+0

はい、「選択されました!」 TextBlockは、選択項目が変更されると(INotifyPropertyChangedサポートのおかげで)、各項目に対して自動的に表示/非表示になります。私は複数の選択のための解決策を示すために私の答えを編集しました。 –

+0

それはかなりうまくいくが、私はXAMLだけで何らかの方法を見つけることを望んでいた....とにかく、ありがとう! – selezen88

関連する問題