Как выбрать шаблон элемента на основе значения? - PullRequest
1 голос
/ 10 мая 2019

У меня есть коллекция объектов, которые я показываю в ItemsControl, и в зависимости от значения в каждом объекте я хочу показать другой ItemTemplate / DataTemplate.Я знаю, что вы можете сделать это с различными типами объектов, но можно ли это сделать на основе значения?

public class MyItem {
    public int MyValue { get; set; }
}

public ObservableCollection<MyItem> MyItems { get; set; }

<ItemsControl ItemsSource="{Binding Path=MyItems}">

<!--If MyValue == 1-->
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid>
                <TextBox/>
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>

<!--If MyValue == 2-->
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid>
                <CheckBox/>
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>

<!--If MyValue == 3-->
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid>
                <ComboBox/>
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>

</ItemsControl>

Ответы [ 2 ]

2 голосов
/ 10 мая 2019

Во-первых, если вы можете сделать это только с помощью триггеров стиля (как в ответе Нила Б.), сделайте.Если ваше значение более сложное, вам может потребоваться другая опция ...

Если у вас есть сложные значения для включения шаблонов, вы можете использовать DataTemplateSelector.Это немного больше накладных расходов / сложностей, но открывает ваши возможности.

public class MyDataTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        FrameworkElement element = container as FrameworkElement;

        if (element != null && item != null && item is MyItem myItem)
        {
            switch (myItem.MyValue)
            {
                case 1:
                    return element.FindResource("TextBoxResource") as DataTemplate;
                case 2:
                    return element.FindResource("CheckBoxResource") as DataTemplate;
                case 3:
                    return element.FindResource("ComboBoxResource") as DataTemplate;
            }
        }

        return null; // or provide a default template
    }
}

Затем в вашем XAML:

<App.Resources>
    <!-- these resources can be in any context such as app, window, or user control, they just need to be in scope -->
    <DataTemplate x:Key="TextBoxResource">
        <Grid>
            <TextBox/>
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="CheckBoxResource">
        <Grid>
            <CheckBox/>
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="ComboBoxResource">
        <Grid>
            <ComboBox/>
        </Grid>
    </DataTemplate>

    <MyDataTemplateSelector x:Key="myDataTemplateSelector"/>
</App.Resources>

<ItemsControl ItemsSource="{Binding Path=MyItems}"
              ItemTemplateSelector="{StaticResource myDataTemplateSelector}">
</ItemsControl>

Селектор шаблона данных затем явно выбирает DataTemplate для предоставления вItemsControl и свойство ItemTemplateSelector ItemsControl являются взаимоисключающими со свойством ItemTemplate (вы не можете установить оба одновременно).

2 голосов
/ 10 мая 2019

Да, вы бы использовали для этого триггеры.

<ItemsControl ItemsSource="{Binding Path=MyItems}">
    <ItemsControl.Style>
        <Style TargetType="ItemsControl">
                <Setter Property="ItemTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <Grid>
                                <!--default template-->
                            </Grid>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
                <Style.Triggers>
                <DataTrigger Binding="{Binding MyValue}" Value="1">
                    <Setter Property="ItemTemplate">
                        <Setter.Value>
                            <DataTemplate>
                                <Grid>
                                    <TextBox/>
                                </Grid>
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
                <DataTrigger Binding="{Binding MyValue}" Value="2">
                    <Setter Property="ItemTemplate">
                        <Setter.Value>
                            <DataTemplate>
                                <Grid>
                                    <CheckBox/>
                                </Grid>
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
                <DataTrigger Binding="{Binding MyValue}" Value="3">
                    <Setter Property="ItemTemplate">
                        <Setter.Value>
                            <DataTemplate>
                                <Grid>
                                    <TextBox/>
                                </Grid>
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ItemsControl.Style>
</ItemsControl>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...