在列表框中显示 canvas children

Showing canvas children in listbox

我是新来的,所以如果我没有添加回答我的问题所需的内容,请原谅。

所以这是我的问题: 我正在尝试向 canvas 添加形状,同时还想在列表框中显示它们的列表,以使它们可变(大小、位置等)。我正在使用 WPF。有办法吗?

如果它不打扰您:是否有关于如何使用鼠标事件动态绘制形状(圆形、椭圆形、矩形等)的问题或网站或其他内容?

希望你能帮助我。提前致谢。

编辑: 鉴于我有:

    public partial class MainWindow : Window
{
    public ObservableCollection<string> Baselist = new ObservableCollection<string>();
    public ObservableCollection<string> Crystallist = new ObservableCollection<string>();
    public ObservableCollection<Shape> Shapelist = new ObservableCollection<Shape>();
    public MainWindow()
    {
        this.ResizeMode = System.Windows.ResizeMode.CanMinimize;
        InitializeComponent();
        InitializeLists(Baseforms,CrystalGroups);
    }

private void InitializeLists(ComboBox Baseforms, ComboBox CrystalGroups)
    {
        Baseforms.ItemsSource = Baselist;
        CrystalGroups.ItemsSource = Crystallist;
        Shape Circle = new Ellipse();
        Circle.Stroke = System.Windows.Media.Brushes.Black;
        Circle.Fill = System.Windows.Media.Brushes.DarkBlue;
        Circle.HorizontalAlignment = HorizontalAlignment.Left;
        Circle.VerticalAlignment = VerticalAlignment.Center;
        Circle.Width = 50;
        Circle.Height = 50;
        Shapelist.Add(Circle);
    }

如何使用 ItemsControl 在 canvas 中显示 Shapelist 中的形状,同时在列表框中列出它们?

希望这能让问题不那么宽泛。

请尝试下一个解决方案:

更新版本(xaml 和代码隐藏)

  1. DetailsList 列表视图 - 基于 ShapeDataPresentation class 呈现详细数据(支持 multi-select)。按名为 ShapeDataPresentationDataTemplate 的数据模板显示数据。
  2. ShapesPresentor 项目控件 - 在 canvas 上呈现形状(不支持多个 select 只能 select 一个)。

ListViewXAML代码(“This”是包含window的ListView的名称)

<Window x:Class="ListViewWithCanvasPanel.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:listViewWithCanvasPanel="clr-namespace:ListViewWithCanvasPanel"
    Title="MainWindow" Height="350" Width="525" x:Name="This" ResizeMode="CanResize">
<Grid>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="2.5*"></ColumnDefinition>
            <ColumnDefinition Width="4*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <ListView x:Name="DetailsList" Panel.ZIndex="999" Grid.Column="0" ItemsSource="{Binding ElementName=This, Path=Shapes}" SelectionMode="Extended" SelectionChanged="Selector_OnSelectionChanged">
            <ListView.Resources>
                <DataTemplate x:Key="ShapeDataPresentationDataTemplate" DataType="listViewWithCanvasPanel:ShapeDataPresentation">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition></ColumnDefinition>
                            <ColumnDefinition></ColumnDefinition>
                            <ColumnDefinition></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <TextBlock Grid.Column="0" Text="{Binding Name, StringFormat={}{0:N0}%}"></TextBlock>
                        <TextBlock Grid.Column="1">
                            <Run Text="W:"></Run>
                            <Run Text="{Binding OriginalRectAroundShape.Width}"></Run>
                        </TextBlock>
                        <TextBlock Grid.Column="2">
                            <Run Text="H:"></Run>
                            <Run Text="{Binding OriginalRectAroundShape.Height}"></Run>
                        </TextBlock>
                    </Grid>
                </DataTemplate>
            </ListView.Resources>
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="ContentTemplate">
                        <Setter.Value>
                            <DataTemplate DataType="Shape">
                               <ContentControl Content="{Binding Tag}" ContentTemplate="{StaticResource ShapeDataPresentationDataTemplate}"></ContentControl>
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListView.ItemContainerStyle>
        </ListView>
        <GridSplitter Grid.Column="0" Width="3" Background="Blue" Panel.ZIndex="999"
          VerticalAlignment="Stretch" HorizontalAlignment="Right" Margin="0"/>
        <ItemsControl Grid.Column="1" x:Name="ShapesPresentor" ItemsSource="{Binding ElementName=This, Path=Shapes}"
                  HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                  MouseDown="UIElement_OnMouseDown">
            <!--<ListView.Resources>
                <ControlTemplate x:Key="SelectedTemplate" TargetType="ListViewItem">
                    <ContentControl Content="{Binding }"></ContentControl>
                </ControlTemplate>
            </ListView.Resources>-->
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas Background="White" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <!--<ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Style.Triggers>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsSelected" Value="true" />
                                <Condition Property="Selector.IsSelectionActive" Value="true" />
                            </MultiTrigger.Conditions>
                            <Setter Property="Template" Value="{StaticResource SelectedTemplate}" />
                        </MultiTrigger>
                    </Style.Triggers>
                </Style>
            </ListView.ItemContainerStyle>-->
        </ItemsControl>
    </Grid>
    <StackPanel VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Orientation="Horizontal">
        <ComboBox x:Name="Baseforms"></ComboBox>
        <ComboBox x:Name="CrystalGroups"></ComboBox>
    </StackPanel>
</Grid>

隐藏代码(更新)

    /// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public static readonly DependencyProperty ShapesProperty = DependencyProperty.Register(
        "Shapes", typeof (ObservableCollection<Shape>), typeof (MainWindow),
        new PropertyMetadata(default(ObservableCollection<Shape>)));

    public ObservableCollection<Shape> Shapes
    {
        get { return (ObservableCollection<Shape>) GetValue(ShapesProperty); }
        set { SetValue(ShapesProperty, value); }
    }

    public ObservableCollection<string> Baselist = new ObservableCollection<string> {"a", "b", "c"};
    public ObservableCollection<string> Crystallist = new ObservableCollection<string>{"aa", "bb", "cc"};

public ObservableCollection<Shape> Shapelist = new ObservableCollection<Shape>();
    private SolidColorBrush _originalColorBrush = Brushes.Tomato;
    private SolidColorBrush _selectedColorBrush;
    private double _diameter;

    public MainWindow()
    {
        _diameter = 50d;
        this.ResizeMode = System.Windows.ResizeMode.CanMinimize;
        Shapes = new ObservableCollection<Shape>();
        InitializeComponent();
        InitializeLists(Baseforms, CrystalGroups);
    }

    private void InitializeLists(ComboBox Baseforms, ComboBox CrystalGroups)
    {
        Baseforms.ItemsSource = Baselist;
        CrystalGroups.ItemsSource = Crystallist;
        Shape Circle = new Ellipse();
        Circle.Stroke = System.Windows.Media.Brushes.Black;
        Circle.Fill = System.Windows.Media.Brushes.DarkBlue;
        Circle.HorizontalAlignment = HorizontalAlignment.Left;
        Circle.VerticalAlignment = VerticalAlignment.Center;
        Circle.Width = 50;
        Circle.Height = 50;
        Shapelist.Add(Circle);
    }


    private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e)
    {
        var inputElement = sender as IInputElement;
        if (inputElement == null) return;
        var point = e.GetPosition(inputElement);
        Shape shape = new Ellipse
        {
            Stroke = Brushes.Black,
            Fill = _originalColorBrush,
            Width = _diameter,
            Height = _diameter
        };
        var byX = point.X - _diameter / 2d;
        var byY = point.Y - _diameter / 2d;

        var existingShape = Shapes.FirstOrDefault(shapeToCheck =>
        {
            var data = shapeToCheck.Tag as ShapeDataPresentation;
            if (data == null) return false;
            var res = data.OriginalRectAroundShape.IntersectsWith(new Rect(point,point));
            return res;
        });

        if (existingShape == null)
        {
            var shapeDataPresentation = new ShapeDataPresentation { Name = string.Format("Ox:{0}, Oy:{1}", point.X.ToString("##.###"), point.Y.ToString("##.###")), OriginalRectAroundShape = new Rect(new Point(byX, byY), new Size(_diameter, _diameter)) };
            shape.Tag = shapeDataPresentation;
            shape.ToolTip = new ToolTip{Content = shapeDataPresentation.Name};
            var translateTransform = new TranslateTransform(byX, byY);
            shape.RenderTransform = translateTransform;
            Shapes.Add(shape);
        }
        else
        {
            if (DetailsList.SelectedItems.Contains(existingShape) == false)
            {
                DetailsList.SelectedItems.Clear();
                DetailsList.SelectedItems.Add(existingShape);
            }
        }


    }

    private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var currentSelected = e.AddedItems.OfType<Shape>().ToList();
        var prevSelected = e.RemovedItems.OfType<Shape>().ToList();
        if (currentSelected.Count > 0)
        {
            currentSelected.ForEach(shape =>
            {
                _selectedColorBrush = Brushes.CadetBlue;
                shape.Fill = _selectedColorBrush;
            });
        }
        if (prevSelected.Count > 0)
        {
            prevSelected.ForEach(shape =>
            {
                shape.Fill = _originalColorBrush;
            });
        }

    }
}

public class ShapeDataPresentation
{
    public string Name { get; set; }
    public Rect OriginalRectAroundShape { get; set; }
}

长得怎么样

总结:

  1. 在这里您可以通过鼠标点击 canvas 创建项目,鼠标按下处理 在代码中 (UIElement_OnMouseDown).
  2. 允许selection和多selection,每次创建selection都会在代码中处理(Selector_OnSelectionChanged)。

但是最好使用基于 MVVM 的方法在 wpf 中工作。

此致。