[WPF] ListViewItem Template 설정 시 오류

[ 질문 ]

ListView의 ItemTemplate를 이용하여 사진과 같이 표현하고 싶은데,
공백화면만 나옵니다.

image
추가된 아이템의 Text, 이미지가 보이질 않습니다.

// MainWindow.xaml
<ListView.ItemTemplate>
      <DataTemplate>
            <StackPanel Grid.Row="0" Grid.RowSpan="2" >
                <Grid>
                    <Grid.Background>
                        <ImageBrush ImageSource="/Img/TestImg.jpg" />
                    </Grid.Background>
                </Grid>
            </StackPanel>
            <TextBlock Text="{Binding files}" Grid.Row="1" Grid.Column="1"/>
            <TextBlock Text="{Binding name}" Grid.Row="1" Grid.Column="0"/>
          </Grid>
      </DataTemplate>
</ListView.ItemTemplate>

[ 오류 테스트 ]

테스트 프로젝트를 생성 - ListView_Template와 관련된 기능만 넣습니다 (+ james.lee 샘플 코드 감사합니다)

Template 정상작동 테스트 완료 후
점차적으로 본 프로젝트와 동일한 환경(UI, 디자인 등)으로 셋팅합니다.
테스트 프로젝트에서 테마 적용 후 본 프로젝트와 동일한 현상 발견

=> image

(적용 된 테마에서) ListView에 관한 Style을 확인합니다.
ListView와 관련된 Style-TargetType은 ListView, GridViewColumnHeader, ListViewItem
이렇게 총 3가지 입니다.

어떤 Style에서 문제가 발생하는지 정확히는 모르기에
Style을 하나씩 제거하는 방식으로 점검했습니다.
테마-Style-TargetType: ListViewItem을 제거 했을 때 Item이 정상적으로 출력되었습니다.

=> image

새로운 Style을 테마의 ListViewItem을 상속받아 생성 후
Template를 새로 설정 해주어 해결 했습니다.

Or < ListVIew.View >를 이용해 Template를 적용 할 수 있습니다.

<ListView.View>
    <GridView>
        <GridViewColumn>
            <GridViewColumn.CellTemplate>
                <DataTemplate>
                    ...

테마를 보면 ListView.View, GridViewColumn와 직접적으로 관련된 Style이 없습니다.
그 이유 중 하나로 안 만들었기 때문에 접근성 인 것 같습니다.
(설명을 못하겠는데요, 커스텀 뷰_PlainView에 관한 내용은 테마보단 스킨에 가까운 것 같습니다.)

ListView, GridViewColumnHeader, ListViewItem의 경우 Style - TargetType로 지정이 가능한 반면
위의 이미지와 같이 바로 지정 해줄 수 없으며, (ListView.View, GridViewColumn의 경우)
ViewBase에서 파생된 PlainView를 통해 설정 할 수 있습니다.

참조 링크 : PlanView 커스텀 뷰 만들기
참조 링크 : ListView.View
참조 링크 : GridViw




[ 개선 방향 ]

아직 사용해보지 못한 기능을 다 같이 구현하려다 보니 문제가 발생했습니다.
그러니 어디서 에러가 발생하는지 갈피를 못 잡겠더군요.
이 점을 해결하기 위해 개발 방식을 변경해야 될 것같습니다

  1. 테스트 프로젝트 생성
  2. 적용할 기능 테스트
  3. 본 프로젝트 적용으로 => 개발 진행
좋아요 2

ImageSource 형식이 올바르지 않은 것 같습니다.
여기서 로드 실패가 일어나 나머지도 같이 렌더링이 안된 것으로 보이는데 한번 확인해보시겠어요?

좋아요 2

잘 모르겠네요 …
랜더링 문제인지 확인하기 위해
ImageSource를 주석처리했지만 안되네요.:face_with_spiral_eyes:

image

원하는 방식은 아니지만 이미지를 넣었습니다…

<ListView.View>
        <GridView>
            <GridViewColumn >
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <Image Source="/Img/TestImg.jpg"
                                   Margin="3,0,3,0"
                                   Height="125"
                                   Width="75" />
                            ...

<ListView.ItemTemplate>를 이용한것이 아닌
(기존코드) ListView.View에서 DataTemplate를 추가 했습니다.

감사합니다.

내일은 이미지컨버터를 시도해보겠습니다.
=> c# - Display Image in WPF Listview - Stack Overflow

그 다음 기회가 온다면 커스텀 뷰까지 가볼게요
=> 방법: ListView의 사용자 지정 뷰 모드 만들기 - WPF .NET Framework | Microsoft Docs

PlainView에 대한 내용이 종종 보이던데요.
이 것 보편적으로 사용하는 건가요?
=> (ListView 설정할 때?)

좋아요 1

아 이미지를 리소스로 넣어서 사용하는게 아니셨군요…
이 부분을 생각 못했네요… :cry:

저는 PlainView는 써본 기억이 없어 이 부분에 답변은 못 드릴 것 같아요

좋아요 2

먼저 디자인 테스트 후 이미지 가져올 방식을 변경 할것 입니다.
=> 이미지는 추후에 파일에 있는 앨범이미지 or 윈도우 기본 이미지를 가져올 예정입니다.

댓글 감사합니다 :+1:

좋아요 1

넘 잘하고 계십니다!
스스로 발전하고자 하시는 의지와 계속 실천하는 것이 중요한 것 같아요.

응원합니다!!

좋아요 2

마음이 조급했나봅니다.(좋은 실력을 기대하지만 그 에 따라가질 못하고 있거든요)
진정하고 계속 정진해나가 겠습니다.

감사합니다. :ok_hand:

좋아요 2

@Stupid 하시려는게 이게 맞을까요?

실행 이미지


XAML


이미지 파일의 빌드속성은 Resource 입니다.

이미지를 ImageBrush 리소스로 따로 만든 이유는 별 뜻이 없습니다. 소스코드가 짤릴까봐 위로 빼놓은겁니다. :smile:

그리고 Grid Background에 ImageBrush를 해주셨잖아요?

그럼 Width, Height 사이즈를 지정해주셔야 합니다. (기본이 Auto으로 설정되어있기 때문에)

<ListView ItemsSource="{Binding Files}">
    <ListView.Resources>
        <ImageBrush x:Key="img" 
                    ImageSource="/ListViewExample1;component/Images/vs.png"/>
    </ListView.Resources>
    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <StackPanel Grid.Row="0" Grid.RowSpan="2">
                    <Grid Width="50" Height="50">
                        <Grid.Background>
                            <ImageBrush ImageSource="img"/>
                        </Grid.Background>
                    </Grid>
                </StackPanel>
                <TextBlock Text="{Binding FileName}" 
                            Grid.Row="0" 
                            Grid.Column="1" 
                            VerticalAlignment="Bottom"/>
                <TextBlock Text="{Binding FullPath}" 
                            Grid.Row="1" 
                            Grid.Column="1" 
                            VerticalAlignment="Top"/>
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

ViewModel


간단한 List 타입의 임시 데이터 Files 준비

public class MainViewModel
{
    public List<FileData> Files { get; set; }
    public string Name { get; set; } = "james";

    public MainViewModel()
    {
        List<FileData> fileDatas = new();
        fileDatas.Add(new FileData { FileName = "RefCount.txt", 
            FullPath = @"C:\Program Files (x86)\Common Files" });
        fileDatas.Add(new FileData { FileName = "Adobe Desktop Service.exe", 
            FullPath = @"C:\Program Files (x86)\Common Files" });
        Files = fileDatas;
    }
}

저도 제 깃허브 레포에 간단하게 샘플로 올려두었습니다. :smile:

좋아요 3

@james.lee 와 소중한 샘플 감사합니다. :smile:

샘플에 있는 ViewModel, Model을 가져와서 적용했는데
같은 현상입니다.
많은 테스트가 필요 할 것같네요.

테스트를 마쳤습니다.
적용중인 테마와 관련해서 문제가 생긴것 같습니다.

제 프로젝트와 비슷한 환경에서 샘플코드가 작동하는지 확인해보았습니다.
우선 저는 item을 dragdrop으로 추가하기 때문에 잘못된 방식을 사용하는 것으로 추측했습니다.
(코드에서 바로 item추가하는 것과는 조금 다르기 때문에)

image
TestListTemplate 테스트 프로젝트를 생성하고 동작하는 것을 확인했습니다.
그 다음으로 디자인을 원래 진행중이던 프로젝트와 조금씩 조금씩 같게 만들었습니다.

Gird, Row, Column, 하나씩 추가해던 중 Dark 테마를 적용 후

=>image

원래 진행중인 프로젝트와 같은 현상이 나옵니다.

저장소 : <링크>



+++ 추가

image
기존 프로젝트에 테마를 벗긴 후 이미지가 잘 나옵니다.

테마를 파바야겠네요.

저장소 : <링크>


궁금한게 있습니다.

public void ListDrag(object sender, DragEventArgs e)
{
    var AddItem = sender as ListView;
    string[] abc = (string[])e.Data.GetData(DataFormats.FileDrop);
    foreach (string fileName in abc)
    {
        _songList.Add(new ListModel() { files = fileName });
    }
  
    AddItem.ItemsSource = _songList;  <<===== 
    AddItem.Items.Refresh();
}

> AddItem.ItemsSource = _songList;

위의 소스와 같이 바인딩이 아닌 코드에서 ListView 아이템을 지정해주게 되는데요.
이렇게 사용해도 괜찮은건가요?

Or

( <ListView itemsSource="{Binding _songList}"> )


++ 추가

테마에서 ListViewItem-Template을 설정해서 오류가 났습니다.

<Style x:Key="DarkListViewItem" TargetType="{x:Type ListViewItem}" />
        <Setter Property="Template">
          ...

<Style TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource DarkListViewItem}" >
        <Setter Property="Template">
          ...

테마의 스타일을 BasedOn으로 넘겨 받고 Template에 대해 재정의 했습니다.
재정의시 문제점이 Gird, 이미지 등 몇개의 줄을 추가하기위해
테마 Template의 모든 내용을 그대로 써줘야합니다.


(출처 : MS문서 - Style.BasedOn 속성)
새 스타일에서 재정의시 상속을 못 받기 때문입니다.

image
현재 기능은 잘 됩니다.
@james.lee 샘플 코드 감사합니다.
샘플 코드로 테스트하고 문제를 파악 및 해결 할 수 있었습니다.
감사합니다.

좋아요 3