WPF ListBox의 ItemContainer 기본 객체 변경 방법?

안녕하세요.

WPF ListBox의 ItemContainer를 다른 객체를 변경하는 방법이 궁금합니다.
ListBox의 기본 Container는 ListBoxItem인데요. 저는 이 부분에서 새로운 클래스로 대체하고자 합
니다.

사실 오래전에 Stackoverflow에 질문했던 질문이었는데 해결하질 못했었는데요. 다시 이 부분을 해결해야할 상황이 생겼습니다. 그래도 그 과정에서 ListBox에서 제공하는 Container 설정 관련 있을만한 Virtual 메서드 단서는 찾았습니다.

PrepareContainerForItemOverride
ShouldApplyItemContainerStyle
GetContainerForItemOverride
IsItemItsOwnContainerOverride

해결하기 위해 계속 시도중입니다만, 문제를 같이 공유도 하고자 질문 드립니다.l
감사합니다. :slight_smile:


(아래는 제가 시도해 본 내용입니다.)

JamesBox (ListBox)
JamesItem (ListBoxItem)

public class JamesBox : ListBox
{    
}

public class JamesItem : ListBoxItem
{   
}

Resource

<!-- ItemContainer JamesItem으로 변경된다면 적용 될 JamesItem -->
<Style TargetType="{x:Type uc:JamesItem">
     <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type uc:JamesItem">
                <Border>
                    <TextBlock Text="적용된다면~"/>
                </Border>
            </Controltemplate>
        </Setter.Value>
    </Setter>
</Style>

정적으로 등록하면 됩니다.

    public class JamesBox : ListBox
    {
    }

    public class JamesItem : ListBoxItem
    {

    }
    <Grid>
        <Grid.Resources>
            <Style TargetType="{x:Type local:JamesItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type local:JamesItem}">
                            <Border>
                                <TextBlock Text="적용된다면~"/>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Grid.Resources>

        <local:JamesBox x:Name="jamesBox">
            <local:JamesItem Content="1"/>
            <local:JamesItem Content="2"/>
            <local:JamesItem Content="3"/>
            <local:JamesItem Content="4"/>
            <local:JamesItem Content="5"/>
        </local:JamesBox>
    </Grid>

하지만 원하시는 건 바인딩 했을때 겠죠? ^^;

좋아요 1
    <Grid>
        <Grid.Resources>
            <Style TargetType="{x:Type local:JamesItem}">
                <Setter Property="Foreground" Value="Red" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type local:JamesItem}">
                            <Border>
                                <TextBlock Text="{Binding}"/>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Grid.Resources>

        <!--<local:JamesBox x:Name="jamesBox">
            <local:JamesItem Content="1"/>
            <local:JamesItem Content="2"/>
            <local:JamesItem Content="3"/>
            <local:JamesItem Content="4"/>
            <local:JamesItem Content="5"/>
        </local:JamesBox>-->

        <local:JamesBox x:Name="jamesBox" ItemsSource="{Binding Items}" />
        <!--<ListBox x:Name="listBox" ItemsSource="{Binding Items}" />-->
    </Grid>

잘 적용되는지를 보기 위해 ForegroundRed를 주었습니다.

그리고 JamesBox에 GetContainerForItemOverride()를 재정의 하였습니다.

    public class JamesBox : ListBox
    {
        protected override DependencyObject GetContainerForItemOverride()
        {
            return new JamesItem();
        }
    }

image

원하시는 결과인가요?

좋아요 1

원했던 결과입니다!!
도와주셔서 감사합니다. :smile:

좋아요 1