如何从不同的ObservableCollection集合绑定到ContentTemplate中的每个canvas?

问题描述 投票:0回答:1

我看了几个关于这个话题的答案,但我还是不明白,请问如何在ContentTemplate中从不同的ObservableCollection集合绑定到每个canvas?如何在ContentTemplate中把不同的ObservableCollection集合绑定到每个画布上?

<TabControl x:Name="Drawing_TabControl"
                        Grid.Row="0"
                        Background="WhiteSmoke"
                        SelectionChanged="Drawing_TabControl_SelectionChanged"
                        ItemsSource="{Binding New_File_Models}"
                        SelectedItem="{Binding Selected_File_Model}">
                <TabControl.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal"
                                    Background="Transparent">
                            <TextBlock Text="{Binding Path=Header}" Background="Transparent" />
                            <Button Height="18"
                                    Width="18"
                                    Background="Transparent"
                                    BorderBrush="Transparent"
                                    Click="Close_TabItem"
                                    Visibility="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType=TabItem},
                                                 Converter={StaticResource B2V}}">
                                <Image  Source="icons\close_x.png"/>
                            </Button>
                        </StackPanel>
                    </DataTemplate>
                </TabControl.ItemTemplate>
                <TabControl.ContentTemplate>
                    <DataTemplate>

                        <Grid Background="WhiteSmoke">
                            <Canvas x:Name="a"
                                    Background="GhostWhite"
                                    Height="6cm"
                                    Width="16cm"
                                    HorizontalAlignment="Center"
                                    VerticalAlignment="Center">
                            </Canvas>
                            <Canvas x:Name="b"
                                    Background="Transparent"
                                    Height="6cm"
                                    Width="16cm"
                                    HorizontalAlignment="Center"
                                    VerticalAlignment="Center"
                                    SizeChanged="gridCanvas_SizeChanged"></Canvas>
                            <Border BorderBrush="Black"
                                    BorderThickness="0.5 0.5 0.5 0.5"
                                    Height="4cm"
                                    Width="14cm"
                                    HorizontalAlignment="Center"
                                    VerticalAlignment="Center"></Border>
                            <Canvas  x:Name="c"
                                    Background="White"
                                    Height="4cm"
                                    Width="14cm"
                                    HorizontalAlignment="Center"
                                    VerticalAlignment="Center"></Canvas>
                            <Canvas x:Name="d"
                                    Background="Transparent"
                                    Height="4cm"
                                    Width="14cm"
                                    HorizontalAlignment="Center"
                                    VerticalAlignment="Center"></Canvas>
                            <Canvas x:Name="e"
                                    Background="Transparent"
                                    Height="4cm"
                                    Width="14cm"
                                    HorizontalAlignment="Center"
                                    VerticalAlignment="Center"
                                    ClipToBounds="True"></Canvas>
                        </Grid>
                    </DataTemplate>
                </TabControl.ContentTemplate>

            </TabControl>

任务如下。1.各种几何形状(Ellipse, Line, Rectangle等)都画在上面。Canvas x:Name="e". 这些数据将被保存到一个文件中。2.其他画布是辅助绘制静态数据,如标记、网格等,它们不会被保存到文件中。

canvas observablecollection tabcontrol contenttemplate
1个回答
0
投票

在研究了 嵌套式观测集合的答案。首先,我重新设计了XAML标记,将其替换为 canvaslistbox:

<Window.Resources>
        <DataTemplate x:Key="EllipseTemplate"
                      DataType="{x:Type local2:Figure_M}">
            <ItemsControl ItemsSource="{Binding Path=Ellipses}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate DataType="{x:Type local3:Ellipse_M}">
                        <Ellipse Stroke="Black"
                                 StrokeThickness="1"
                                 Width="{Binding Width}"
                                 Height="{Binding Height}"
                                 Cursor="Hand" />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DataTemplate>
        <DataTemplate x:Key="LineTemplate"
                      DataType="{x:Type local2:Figure_M}">
            <ItemsControl ItemsSource="{Binding Path=Lines}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate DataType="{x:Type local3:Line_M}">
                        <Line Stroke="Black"
                                 StrokeThickness="1"
                              X1="{Binding X1}"
                              X2="{Binding X2}"
                              Y1="{Binding Y1}"
                              Y2="{Binding Y2}"
                              Cursor="Hand" />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DataTemplate>
        <DataTemplate x:Key="RectangleTemplate"
                      DataType="{x:Type local2:Figure_M}">
            <ItemsControl ItemsSource="{Binding Path=Rectangles}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate DataType="{x:Type local3:Rectangle_M}">
                        <Rectangle Stroke="Black"
                                 StrokeThickness="1"
                                 Width="{Binding Width}"
                                   Height="{Binding Height}"
                                   Cursor="Hand" />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DataTemplate>
    </Window.Resources>

<TabControl x:Name="Drawing_TabControl"
                        Grid.Row="0"
                        Background="WhiteSmoke"
                        SelectionChanged="Drawing_TabControl_SelectionChanged"
                        ItemsSource="{Binding Files}"
                        SelectedItem="{Binding SelectedFile_M}">
                <TabControl.ItemTemplate>
                    <DataTemplate DataType="{x:Type local1:File_M}">
                        <StackPanel Orientation="Horizontal"
                                    Background="Transparent">
                            <TextBlock Text="{Binding Path=Name_File}" Background="Transparent" />
                            <Button Height="18"
                                    Width="18"
                                    Background="Transparent"
                                    BorderBrush="Transparent"
                                    Click="Close_TabItem"
                                    Visibility="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType=TabItem},
                                                 Converter={StaticResource B2V}}">
                                <Image  Source="icons\close_x.png"/>
                            </Button>
                        </StackPanel>
                    </DataTemplate>
                </TabControl.ItemTemplate>
                <TabControl.ContentTemplate>
                    <DataTemplate DataType="{x:Type local1:File_M}">
                        <Grid Background="WhiteSmoke">
                            <Grid>
                                <Canvas x:Name="a"
                                        Background="GhostWhite"
                                        Height="6cm"
                                        Width="16cm"
                                        HorizontalAlignment="Center"
                                        VerticalAlignment="Center">
                                </Canvas>
                                <Canvas x:Name="b"
                                        Background="Transparent"
                                        Height="6cm"
                                        Width="16cm"
                                        HorizontalAlignment="Center"
                                        VerticalAlignment="Center"
                                        SizeChanged="gridCanvas_SizeChanged"></Canvas>
                                <Border BorderBrush="Black"
                                        BorderThickness="0.5 0.5 0.5 0.5"
                                        Height="4cm"
                                        Width="14cm"
                                        HorizontalAlignment="Center"
                                        VerticalAlignment="Center"></Border>
                                <Canvas  x:Name="c"
                                         Background="White"
                                         Height="4cm"
                                         Width="14cm"
                                         HorizontalAlignment="Center"
                                         VerticalAlignment="Center"></Canvas>
                                <Canvas x:Name="d"
                                        Background="Transparent"
                                        Height="4cm"
                                        Width="14cm"
                                        HorizontalAlignment="Center"
                                        VerticalAlignment="Center"></Canvas>
                            </Grid>
                            <ListBox ItemsSource="{Binding Path=Figures}"
                                     SelectedItem="{Binding Path=SelectedFigure_M}"
                                     SelectionMode="Multiple"
                                     Background="Transparent"
                                     Height="4cm"
                                     Width="14cm"
                                     HorizontalAlignment="Center"
                                     VerticalAlignment="Center">
                                <ListBox.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <Canvas />
                                    </ItemsPanelTemplate>
                                </ListBox.ItemsPanel>
                                <ListBox.ItemTemplateSelector>
                                    <local:FigureTemplateSelector EllipseTemplate="{StaticResource EllipseTemplate}"
                                                                  LineTemplate="{StaticResource LineTemplate}"
                                                                  RectangleTemplate="{StaticResource RectangleTemplate}" />
                                </ListBox.ItemTemplateSelector>
                                <ListBox.ItemContainerStyle>
                                    <Style TargetType="ListBoxItem">
                                        <Setter Property="Canvas.Left"
                                                Value="{Binding X}" />
                                        <Setter Property="Canvas.Top"
                                                Value="{Binding Y}" />
                                        <Setter Property="Template">
                                            <Setter.Value>
                                                <ControlTemplate TargetType="ListBoxItem">
                                                    <Border Name="Border"
                                                            BorderThickness="1"
                                                            Padding="1">
                                                        <ContentPresenter Name="Content" />
                                                    </Border>
                                                    <ControlTemplate.Triggers>
                                                        <Trigger Property="IsSelected"
                                                                 Value="true">
                                                            <Setter TargetName="Border"
                                                                    Property="BorderBrush"
                                                                    Value="Blue" />
                                                        </Trigger>
                                                    </ControlTemplate.Triggers>
                                                </ControlTemplate>
                                            </Setter.Value>
                                        </Setter>
                                    </Style>
                                </ListBox.ItemContainerStyle>
                            </ListBox>
                        </Grid>
                    </DataTemplate>
                </TabControl.ContentTemplate>
                
            </TabControl>

接下来我创建了一个数据模型。

class Ellipse_M :

public class Ellipse_M : INotifyPropertyChanged
    {
        #region DataMembers
        private double x = 0;
        private double y = 0;
        private double width = 0;
        private double height = 0;
        #endregion DataMembers

        public double X
        {
            get
            {
                return x;
            }
            set
            {
                if (x == value)
                {
                    return;
                }

                x = value;

                OnPropertyChanged("X");
            }
        }

        public double Y
        {
            get
            {
                return y;
            }
            set
            {
                if (y == value)
                {
                    return;
                }

                y = value;

                OnPropertyChanged("Y");
            }
        }

        public double Width
        {
            get
            {
                return width;
            }
            set
            {
                if (width == value)
                {
                    return;
                }

                width = value;

                OnPropertyChanged("Width");
            }
        }

        public double Height
        {
            get
            {
                return height;
            }
            set
            {
                if (height == value)
                {
                    return;
                }

                height = value;

                OnPropertyChanged("Height");
            }
        }


        #region INotifyPropertyChanged Members

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }

類線條_M。

public class Line_M : INotifyPropertyChanged
    {
        #region DataMembers
        private double x1 = 0;
        private double y1 = 0;
        private double x2 = 0;
        private double y2 = 0;
        #endregion DataMembers

        public double X1
        {
            get
            {
                return x1;
            }
            set
            {
                if (x1 == value)
                {
                    return;
                }

                x1 = value;

                OnPropertyChanged("X1");
            }
        }

        public double Y1
        {
            get
            {
                return y1;
            }
            set
            {
                if (y1 == value)
                {
                    return;
                }

                y1 = value;

                OnPropertyChanged("Y1");
            }
        }

        public double X2
        {
            get
            {
                return x2;
            }
            set
            {
                if (x2 == value)
                {
                    return;
                }

                x2 = value;

                OnPropertyChanged("X2");
            }
        }

        public double Y2
        {
            get
            {
                return y2;
            }
            set
            {
                if (y2 == value)
                {
                    return;
                }

                y2 = value;

                OnPropertyChanged("Y1");
            }
        }



        #region INotifyPropertyChanged Members

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }

类 矩形_M : 类 矩形_M :

public class Rectangle_M : INotifyPropertyChanged
    {
        #region DataMembers
        private double x = 0;
        private double y = 0;
        private double width = 0;
        private double height = 0;
        #endregion DataMembers

        public double X
        {
            get
            {
                return x;
            }
            set
            {
                if (x == value)
                {
                    return;
                }

                x = value;

                OnPropertyChanged("X");
            }
        }

        public double Y
        {
            get
            {
                return y;
            }
            set
            {
                if (y == value)
                {
                    return;
                }

                y = value;

                OnPropertyChanged("Y");
            }
        }

        public double Width
        {
            get
            {
                return width;
            }
            set
            {
                if (width == value)
                {
                    return;
                }

                width = value;

                OnPropertyChanged("Width");
            }
        }

        public double Height
        {
            get
            {
                return height;
            }
            set
            {
                if (height == value)
                {
                    return;
                }

                height = value;

                OnPropertyChanged("Height");
            }
        }



        #region INotifyPropertyChanged Members

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }

类 Figure_M : 类 Figure_M :

public class Figure_M : INotifyPropertyChanged
    {
        #region DataMembers(Ellipse_M, Line_M, Rectangle_M)
        private double x = 0;
        private double y = 0;
        private Ellipse_M selectedEllipse_M;
        private Line_M selectedLine_M;
        private Rectangle_M selectedRectangle_M;

        private string selectedFigure = "";
        #endregion DataMembers(Ellipse_M, Line_M, Rectangle_M)

        public Figure_M()
        {
                    Ellipses = new ObservableCollection<Ellipse_M>();
                    Lines = new ObservableCollection<Line_M>();
                    Rectangles = new ObservableCollection<Rectangle_M>();
        }


        #region Property of Collections

        public ObservableCollection<Ellipse_M> Ellipses { get; set; }
        public ObservableCollection<Line_M> Lines { get; set; }
        public ObservableCollection<Rectangle_M> Rectangles { get; set; }

        #endregion Property of Collections

        #region Property of DataMembers

        public Ellipse_M SelectedEllipse_M
        {
            get { return selectedEllipse_M; }
            set
            {
                if (value != selectedEllipse_M)
                {
                    selectedEllipse_M = value;
                    OnPropertyChanged();
                }
            }
        }
        public Line_M SelectedLine_M
        {
            get { return selectedLine_M; }
            set
            {
                if (value != selectedLine_M)
                {
                    selectedLine_M = value;
                    OnPropertyChanged();
                }
            }
        }
        public Rectangle_M SelectedRectangle_M
        {
            get { return selectedRectangle_M; }
            set
            {
                if (value != selectedRectangle_M)
                {
                    selectedRectangle_M = value;
                    OnPropertyChanged();
                }
            }
        }

        public string SelectedFigure
        {
            get { return selectedFigure; }
            set
            {
               selectedFigure = value;
                
            }
        }

        public double X
        {
            get { return x; }
            set
            {
                if (value != x)
                {
                    x = value;
                    OnPropertyChanged();
                }
            }
        }

        public double Y
        {
            get { return y; }
            set
            {
                if (value != y)
                {
                    y = value;
                    OnPropertyChanged();
                }
            }
        }



        #endregion Property of DataMembers




        #region INotifyPropertyChanged Members

        /// <summary>
        /// Raises the 'PropertyChanged' event when the value of a property of the view model has changed.
        /// </summary>
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }

类File_M:类File_M。

public class File_M : INotifyPropertyChanged
    {
        #region DataMembers
        private string name_File;
        private Figure_M selectedFigure_M;
        #endregion DataMembers
        public string Name_File
        {
            get { return name_File; }
            set
            {
                name_File = value;
                OnPropertyChanged("Name_File");
            }
        }
        public File_M()
        {
            Figures = new ObservableCollection<Figure_M>();
        }

        #region Property of Collections
        public ObservableCollection<Figure_M> Figures { get; set; }

        #endregion Property of Collections

        #region Property of DataMembers

        public Figure_M SelectedFigure_M
        {
            get { return selectedFigure_M; }
            set
            {
                if (value != selectedFigure_M)
                {
                    selectedFigure_M = value;
                    OnPropertyChanged();
                }
            }
        }

        #endregion Property of DataMembers




        #region INotifyPropertyChanged Members

        /// <summary>
        /// Raises the 'PropertyChanged' event when the value of a property of the view model has changed.
        /// </summary>
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }

ViewModel。

public class ViewModel : INotifyPropertyChanged
    {
        #region DataMembers

        private File_M selectedFile_M;

        #endregion DataMembers
        public ViewModel()
        {
            Files = new ObservableCollection<File_M>();
            for(int i = 0; i < 3; i++)
            {
                File_M file_M = new File_M();
                file_M.Name_File = $"Макет_{i + 1}";
                for (int j = 3; j >= 0; j--)
                {
                    Figure_M figure_M = new Figure_M();
                    Ellipse_M ellipse_M = new Ellipse_M();
                    ellipse_M.Height = 25 + j * 50;
                    ellipse_M.Width = 35 + j * 50;
                    figure_M.X = 70 + j*80;
                    figure_M.Y = 50;
                    figure_M.Ellipses.Add(ellipse_M);
                    file_M.Figures.Add(figure_M);
                }
                for (int j = 3; j >= 0; j--)
                {
                    Figure_M figure_M = new Figure_M();
                    Line_M line_M = new Line_M();
                    line_M.X2 = 100 + j * 80;
                    line_M.Y2 = 100;
                    figure_M.X = 10 + j * 80;
                    figure_M.Y = 10;
                    figure_M.Lines.Add(line_M);
                    file_M.Figures.Add(figure_M);
                }
                for (int j = 3; j >= 0; j--)
                {
                    Figure_M figure_M = new Figure_M();
                    Rectangle_M rectangle_M = new Rectangle_M();
                    rectangle_M.Height = 25 + j * 20;
                    rectangle_M.Width = 35 + j * 20;
                    figure_M.X = 70 + j * 80;
                    figure_M.Y = 50;
                    figure_M.Rectangles.Add(rectangle_M);
                    file_M.Figures.Add(figure_M);
                }
                Files.Add(file_M);

            }

        }

        public ObservableCollection<File_M> Files { get; set; }

        #region Property of DataMembers

        public File_M SelectedFile_M
        {
            get { return selectedFile_M; }
            set
            {
                if (value != selectedFile_M)
                {
                    selectedFile_M = value;
                    OnPropertyChanged();
                }
            }
        }

        #endregion Property of DataMembers


        #region INotifyPropertyChanged Members

        /// <summary>
        /// Raises the 'PropertyChanged' event when the value of a property of the view model has changed.
        /// </summary>
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }

为了能够选择此刻要放置的形状,我创建了 FigureTemplateSelector 。

public class FigureTemplateSelector : DataTemplateSelector
    {
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            DataTemplate template = null;
            Figure_M figure_M = item as Figure_M;
            if (figure_M.Ellipses.Count > 0)
            {
                template = EllipseTemplate;
                if (template == null)
                {
                    template = base.SelectTemplate(item, container);
                }
            }
            else if(figure_M.Lines.Count > 0)
            {
                template = LineTemplate;
                if (template == null)
                {
                    template = base.SelectTemplate(item, container);
                }
            }
            else if (figure_M.Rectangles.Count > 0)
            {
                template = RectangleTemplate;
                if (template == null)
                {
                    template = base.SelectTemplate(item, container);
                }
            }
            else
            {
                template = base.SelectTemplate(item, container);
            }

            return template;
        }

        public DataTemplate EllipseTemplate { get; set; }

        public DataTemplate LineTemplate { get; set; }

        public DataTemplate RectangleTemplate { get; set; }
    }

其他的画布都是辅助性的,所以我认为我们也应该这样做,在里面创建一个集合。Figure 类。

© www.soinside.com 2019 - 2024. All rights reserved.