2017-12-17 1 views
2

"hover"및 "selected"상태의 항목이 있고 각 상태마다 다른 내용을 표시하는 ListView를 만들고 싶습니다.숨기기 가능한 콘텐츠로 ListViewItem을 올바르게 사용자 정의하고 UWP의 모델에 바인딩하는 방법은 무엇입니까?

StackOverflow에 대한 비슷한 질문이 있지만 내 경우에는 아무런 도움이되지 못했습니다.

의가 나는 모델 있다고 가정 해 봅시다 :

public class TagFile : BaseBind // A class with INotifyProperyChanged interface 
{ 
    private string path; 
    public String Path 
    { 
     get { return path; } 
     set 
     { 
      SetProperty(ref path, value); 
     } 
    } 

    public void SelectButtonClick() 
    { 
     // Do something 
    } 

    public void HoverButtonClick() 
    { 
     // Do something 
    } 
} 

를 ... 그때는 메인 뷰 모델 있습니다

public class AppViewModel : BaseBind 
{ 
    public ObservableCollection<TagFile> ItemsList { get; set; } 

    // Other things 
} 

을 ... 다음 페이지 :

<Grid> 
    <ListView ItemsSource="ItemsList"> 
      <ListView.ItemTemplate> 
       <DataTemplate x:DataType="local:TagFile"> 
        <Grid> 
          <Grid.RowDefinitions> 
           <RowDefinition/> 
           <RowDefinition/> 
           <RowDefinition/> 
          </Grid.RowDefinitions> 
          <TextBlock Text="{x:Bind Path, mode=OneWay}"/> 
          <Button Content="Select Button" Click="{x:Bind SelectButtonClick}"/> 
          <Button Content="Hover Button" Click="{x:Bind HoverbuttonClick}"/> 
        </Grid> 
       </DataTemplate> 
      </ListView.ItemTemplate> 
    </ListView> 
</Grid> 

ListViewItem이 선택되었을 때만 SelectButton이 나타나게하고 커서가있을 때만 HoverButton이 나타나도록 ListViewItem Style을 커스터마이징하고 싶습니다.

나는 ItemTemplate과 ItemContainerStyle을 가지고 놀 필요가 있음을 이미 알고 있지만, 처음부터 끝까지 힘들 것 같다. ItemContainerStyle에 대한 사용자 정의 스타일을 이렇게 만들 수 있기 때문이다 (IsSelected 속성을 사용하여 있는 ListViewItem) :

<Style TargetType="ListViewItem" x:Key="TestContainerStyle"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="ListViewItem"> 
        <Grid> 
         <Grid.RowDefinitions> 
          <RowDefinition Height="Auto"/> 
          <RowDefinition Height="Auto"/> 
         </Grid.RowDefinitions> 
         <ContentPresenter x:Name="Presenter" Content="{TemplateBinding Content}"/> 
         <Button Grid.Row="1" Content="Select Button" Visibility="{Binding IsSelected, RelativeSource={RelativeSource Mode=TemplatedParent}}"/> 
        </Grid> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
     <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 
    </Style> 

...하지만이 방법 : 1) 나는 모든 기본 브러쉬를 풀어; 2) SelectButton을 모델의 명령에 바인딩 할 수있는 방법을 모르겠습니다. 3) HoverButton을 표시하기 위해 "hover"상태에 대한 방법을 찾아야합니다. 4) 마지막으로, 중요하지 않은 것은 ... 모든 사용자 정의 내용을 App.xaml 파일 (또는 관련 ResourceDictionary 파일에 전체 응용 프로그램에서 필요로 함)에 포함시키고 싶습니다.

이것은 ... 내가 StackOverflow 답변에서 다양한 패턴을 시도했지만 내 경우에는 많은 differnt 것들이 포함되어 있습니다 (App.xaml 파일에서 바인딩 컴파일, "호버"상태 만들기, 데이터 유형없이 스타일에서 바인딩 사용). , 등) 여기에 개별적으로 응답합니다.

나는 그들을 모두 모으고, 내가 생각한 것보다 생각보다 더 까다로운 것처럼 보인다.

감사합니다. 정말로 감사드립니다.

편집 : 동작은 Groove App 목록 항목과 같아야합니다. 일부 단추 (재생 및 제거 항목)는 항목이 선택되거나 호버 상태 일 때만 나타납니다.

정상 상태 :

enter image description here

...및 호버/선택 상태 :

첫 번째 :나는 그것이 당신 것으로 선호하지 않는

enter image description here

+0

내가 부분적으로 도움이 될 수 있습니다 생각합니다. 나 자신도 스타일을 배우기 전에 데이터 바인딩을 시도한 적이 없다. 이벤트를 사용하는 대신 컨트롤 입력을 뷰 모델 메서드에 바인딩 할 수 있습니다. 단추 만 클릭하면 ICommand 인터페이스를 사용할 수 있습니다. 마우스를 올려 놓는 것과 같은 고급 입력의 경우 [상호 작용] (https://stackoverflow.com/questions/36221118/how-to-make-mouseover-event-in-mvvm)을 사용해야합니다. –

+0

또한 XAML에서 저의 경험 (제한적 임)에도 불구하고 스타일 템플릿에 브러쉬 등을 보관하려는 경우 기본 템플릿에있는 모든 것을 포함 할 필요가 없습니까? –

+0

@ SeanO'Neil, ListViewItem의 기본 스타일은 처리하기 어려운 ListViewItemPresenter를 포함합니다 ... 아마도 ItemContainerStyle이 아닌 ItemContainerStyle의 기본값을 검색 할 때 올바른 것일 수도 있습니다. ListViewItem 스타일 ... – LucaLindholm

답변

0

당신이 원하는 무엇을 달성 할 수있는 방법은 두 가지가 있습니다 전체 스타일을 복사하고 스타일 안에 항목 템플릿을 포함해야합니다. 또한 앱의 여러 부분에서 동일한 동작을 원할 경우 확장되지 않습니다.

ListViewItemPresenter 대신 UIElement 트리와 시각적 상태를 사용하는 ListViewItem style을 복사 할 수 있습니다. 이렇게하면 기본 브러쉬가 손실되지 않습니다.

참고 : 위의 링크에서 x:Key="ListViewItemExpanded" 템플릿을 찾으십시오.

<!-- Style for Windows.UI.Xaml.Controls.ListViewItem --> 
<Style TargetType="ListViewItem" x:Key="ListViewItemExpanded"> 

둘째 주 :

이 스타일과 자원은 윈도우 10, 버전 1511 (윈도우 SDK 버전 10.0.10586.0)에 대한 Windows 소프트웨어 개발 키트 (SDK)를 기반으로합니다. SDK의 다른 버전의 스타일 및 리소스에는 다른 값이있을 수 있습니다. 디자인을 위해 generic.xaml은 Windows SDK 설치에서 (프로그램 파일) \ Windows Kits \ 10 \ DesignTime \ CommonConfiguration \ Neutral \ UAP \ 10.0.10586.0 \ Generic 폴더에있는 폴더입니다.

이제 표시하고 다른 요소를 숨길 pointeroverselected 상태를 사용할 수 있습니다.

두 번째 방법 : 사용하여 사용자 지정 컨트롤 [추천]

두 가지로 문제를 휴식

: 각 항목에 대한 모델/뷰 모델에에 isSelected 속성을 정의 할 수 있습니다

  1. 및 업데이트가 귀하의 선택 명령 내에서. 이제 IsSelected에 바인딩하여 첫 번째 단추 가시성을 제어 할 수 있습니다.

  2. 두 번째 부분은 종속성 속성 인 IsPointerOver를 표시하는 사용자 지정 컨트롤을 만들고 '호버 단추'의 가시성을 바인딩 할 수 있습니다.

예 :

public class ExtendedControl : ContentControl 
    { 
     public static readonly DependencyProperty IsPointerOverProperty = 
      DependencyProperty.Register("IsPointerOver", typeof(bool), typeof(ExtendedControl), 
       new PropertyMetadata(false)); 

     public bool IsPointerOver 
     { 
      get => (bool)GetValue(IsPointerOverProperty); 
      protected set => SetValue(IsPointerOverProperty, value); 
     } 
     protected override void OnPointerEntered(PointerRoutedEventArgs e) 
     { 
      base.OnPointerEntered(e); 
      IsPointerOver = true; 
     } 
     protected override void OnPointerCanceled(PointerRoutedEventArgs e) 
     { 
      base.OnPointerCanceled(e); 
      IsPointerOver = false; 
     } 
     protected override void OnPointerExited(PointerRoutedEventArgs e) 
     { 
      base.OnPointerExited(e); 
      IsPointerOver = false; 
     } 
    } 

XAML :

<ListView.ItemTemplate> 
      <DataTemplate > 
       <local:ExtendedControl x:Name="ExtendedControl"> 
        <StackPanel> 
         <Button Content="Always Visible"/> 
         <Button Content="Only on hover" Visibility="{x:Bind ExtendedControl.IsPointerOver,Mode=OneWay,Converter={StaticResource BoolToVisibilityConverter}}"/> 
        </StackPanel> 
       </local:ExtendedControl> 
      </DataTemplate> 
     </ListView.ItemTemplate> 
+0

맞춰봐? 나는 지금 혼자서이 해결책을 알아 냈다! 어쨌든 XD에 감사드립니다. – LucaLindholm

관련 문제