Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WPF, Silverlight Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2]      все
 Re: Использование в ListBox.ItemsPanel панели Canvas  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 19959
Eld Hasp
Ещё вариант, до которого сам додумался, сделать один класс для всего со всеми свойствами наследников. И в нём ввести свойство переключающее представление. По этому свойству менять Visibility у элементов в шаблоне. Но это порождает множество элементов, пусть и невидимых. Не слишком ли криво это?
Я поэтому и сказал выше буквально следующее "когда для одного класса существуют принципиально разные шаблоны". А в случае, когда разница между шаблонами в паре [не]видимых элементов, то это как раз и решается триггерами или тупым маппингом свойства Visibility на какое-то поле модели.

Eld Hasp
Если вернуться к началу темы. Для DataTemplate не существует каких-то триггеров, селекторов (или чего-то подобного) позволяющего изменить представление или переключаться между ними?
а) в качестве внешнего селектора, как я сказал, можно использовать TemplateSelector
б) можно переключать триггерами шаблон в ContentPresentere
в) можно реализовать внутри шаблона примерно такую разметку
<Grid>
  <Border Visibility="{Binding...}">
    ...
  </Border>
  <Border Visibility="{Binding...}">
    ...
  </Border>
  <Border Visibility="{Binding...}">
    ...
  </Border>
</Grid>
в общем, решается по месту
16 янв 19, 00:09    [21786304]     Ответить | Цитировать Сообщить модератору
 Re: Использование в ListBox.ItemsPanel панели Canvas  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 3171
сделайте свою панель с блекджеком и всем остальным и реализуйте там логику размещения элементов так, как вашей душе угодно, без всякого гемороя
это только пример, не стоит брать его за основу, Measure не бесконечные размеры, то есть эта панель не будет работать в scrollviewer'е и т.д.
Создайте свою панель и элемент контейнер который будет в ней размещаться, свяжите свойства контейнера с моделью, переопределите метод генерации контейнера в ListBox.
Это будет самый гибкий вариант и чуть более затратный, но не более того.

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace PanelExamples
{
    public class WheelPanel : Panel
    {
        protected override void OnMouseWheel(MouseWheelEventArgs e)
        {
            if (HasAnimatedProperties)
            {
                double oldValue = Offset;
                BeginAnimation(OffsetProperty, null);
                Offset = oldValue;
            }
            Offset += 3.0 / e.Delta;
            base.OnMouseWheel(e);
        }

        public double Radius
        {
            get { return (double)GetValue(RadiusProperty); }
            set { SetValue(RadiusProperty, value); }
        }
        public static readonly DependencyProperty RadiusProperty =
            DependencyProperty.Register("Radius", typeof(double), typeof(WheelPanel), new FrameworkPropertyMetadata(100.0, FrameworkPropertyMetadataOptions.AffectsArrange));

        public double Offset
        {
            get { return (double)GetValue(OffsetProperty); }
            set { SetValue(OffsetProperty, value); }
        }
        public static readonly DependencyProperty OffsetProperty =
            DependencyProperty.Register("Offset", typeof(double), typeof(WheelPanel), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsArrange));

        protected override Size MeasureOverride(Size availableSize)
        {
            foreach (UIElement child in Children)
            {
                child.Measure(availableSize);
            }
            var resultSize = base.MeasureOverride(availableSize);
            return availableSize;
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            double centerX = finalSize.Width / 2.0;
            double centerY = finalSize.Height / 2.0;
            double step = Math.PI * 2 / Children.Count;
            double current = Offset;
            foreach (UIElement child in Children)
            {
                var x = Math.Cos(current) * Radius;
                var y = Math.Sin(current) * Radius;
                current += step;
                var size = child.DesiredSize;
                var pos = new Point(centerX + x - size.Width / 2.0, centerY + y - size.Height / 2.0);
                child.Arrange(new Rect(pos, size));
            }

            return base.ArrangeOverride(finalSize);
        }
    }
}

<Window x:Class="PanelExamples.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:PanelExamples"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <ItemsControl>
            <ItemsControl.ItemsSource>
                <CompositeCollection>
                    <sys:String>Item 1</sys:String>
                    <sys:String>Item 2</sys:String>
                    <sys:String>Item 3</sys:String>
                    <sys:String>Item 4</sys:String>
                    <sys:String>Item 5</sys:String>
                    <sys:String>Item 6</sys:String>
                    <sys:String>Item 7</sys:String>
                    <sys:String>Item 8</sys:String>
                </CompositeCollection>
            </ItemsControl.ItemsSource>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <local:WheelPanel Background="Transparent" Radius="120">
                        <local:WheelPanel.Triggers>
                            <EventTrigger RoutedEvent="Loaded">
                                <EventTrigger.Actions>
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetProperty="Offset" RepeatBehavior="Forever" From="0.0" To="6.2820" Duration="0:0:8"/>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger.Actions>
                            </EventTrigger>
                        </local:WheelPanel.Triggers>
                    </local:WheelPanel>
                    
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate DataType="{x:Type sys:String}">
                    <Button>
                        <Button.Template>
                            <ControlTemplate TargetType="{x:Type Button}">
                                <Grid>
                                    <Ellipse x:Name="PART_Filler" Fill="{TemplateBinding Background}" Width="75" Height="75" />
                                    <TextBlock Text="{Binding}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                                </Grid>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter TargetName="PART_Filler" Property="Fill" Value="LightBlue"/>
                                    </Trigger>
                                             
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Button.Template>
                    </Button>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Window>
16 янв 19, 12:19    [21786573]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2]      все
Все форумы / WPF, Silverlight Ответить