为什么不绑定到画布的宽度和高度?

时间:2022-09-25 12:49:55

Why do not bind to the properties Width and Height of Canvas?

为什么不绑定到画布的宽度和高度?

I tried to do it like that, but it did not .

我试着这样做,但事实并非如此。

  <ItemsControl
                Grid.Row="0"
                ItemsSource="{Binding RectItems}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                                //does not work
                        <Canvas Height="{Binding PanelHeight, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
                                Width="{Binding PanelWidth, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemContainerStyle>
                    <Style TargetType="ContentPresenter">
                        <Setter Property="Canvas.Left" Value="{Binding X}" />
                        <Setter Property="Canvas.Top" Value="{Binding Y}" />
                    </Style>
                </ItemsControl.ItemContainerStyle>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Rectangle
                            Width="{Binding Width}"
                            Height="{Binding Height}"
                            Fill="Black" />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>

2 个解决方案

#1


0  

Those bindings seem to work just fine; just add

这些绑定似乎工作得很好;只需添加

Background="Red"

to the definition of Canvas so that you can SEE the actual Canvas.

到Canvas的定义,以便您可以查看实际的Canvas。

#2


0  

I've made you an example:

我给你举了一个例子:

Classes

 public class RectItem : INotifyPropertyChanged
    {
        private int _width;
        private int _height;
        private int _x;
        private int _y;

        public Brush Color { get; set; }

        public int Width {
            get { return _width; }
            set {
                if (value == _width) return;
                _width = value;
                OnPropertyChanged();
            }
        }

        public int Height {
            get { return _height; }
            set {
                if (value == _height) return;
                _height = value;
                OnPropertyChanged();
            }
        }

        public int X {
            get { return _x; }
            set {
                if (value == _x) return;
                _x = value;
                OnPropertyChanged();
            }
        }

        public int Y {
            get { return _y; }
            set {
                if (value == _y) return;
                _y = value;
                OnPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    internal class ViewModel : INotifyPropertyChanged
    {
        public ViewModel()
        {
            this.RectItems.Add(new RectItem { Height = 100, Width = 100, X = 0, Y = 0, Color = Brushes.DeepPink });
            this.RectItems.Add(new RectItem { Height = 50, Width = 50, X = 100, Y = 100, Color = Brushes.DeepSkyBlue });
        }

        private double _panelWidth = 100;
        private double _panelHeight = 100;
        public ObservableCollection<RectItem> RectItems { get; } = new ObservableCollection<RectItem>();


        public ICommand IncreaseSizeCommand => new RelayCommand(x =>
        {
            this.PanelHeight = 200;
            this.PanelWidth = 200;
        });

        public double PanelWidth {
            get { return _panelWidth; }
            set {
                if (value.Equals(_panelWidth)) return;
                _panelWidth = value;
                OnPropertyChanged();
            }
        }

        public double PanelHeight {
            get { return _panelHeight; }
            set {
                if (value.Equals(_panelHeight)) return;
                _panelHeight = value;
                OnPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

XAML

XAML

<StackPanel>
            <Button Content="Click me" Width="80" Height="20" Command="{Binding IncreaseSizeCommand}"/>
            <ItemsControl
                Grid.Row="0"
                ItemsSource="{Binding RectItems}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas Height="{Binding PanelHeight, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
                                Width="{Binding PanelWidth, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemContainerStyle>
                    <Style TargetType="ContentPresenter">
                        <Setter Property="Canvas.Left" Value="{Binding X}" />
                        <Setter Property="Canvas.Top" Value="{Binding Y}" />
                    </Style>
                </ItemsControl.ItemContainerStyle>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Rectangle
                            Width="{Binding Width}"
                            Height="{Binding Height}"
                            Fill="{Binding Color}" />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
</StackPanel>

Works as aspected. I've added some colors to do some visual highlighting and a command to change the size of the Canvas

按预期工作。我添加了一些颜色来做一些视觉突出显示和一个改变画布大小的命令

#1


0  

Those bindings seem to work just fine; just add

这些绑定似乎工作得很好;只需添加

Background="Red"

to the definition of Canvas so that you can SEE the actual Canvas.

到Canvas的定义,以便您可以查看实际的Canvas。

#2


0  

I've made you an example:

我给你举了一个例子:

Classes

 public class RectItem : INotifyPropertyChanged
    {
        private int _width;
        private int _height;
        private int _x;
        private int _y;

        public Brush Color { get; set; }

        public int Width {
            get { return _width; }
            set {
                if (value == _width) return;
                _width = value;
                OnPropertyChanged();
            }
        }

        public int Height {
            get { return _height; }
            set {
                if (value == _height) return;
                _height = value;
                OnPropertyChanged();
            }
        }

        public int X {
            get { return _x; }
            set {
                if (value == _x) return;
                _x = value;
                OnPropertyChanged();
            }
        }

        public int Y {
            get { return _y; }
            set {
                if (value == _y) return;
                _y = value;
                OnPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    internal class ViewModel : INotifyPropertyChanged
    {
        public ViewModel()
        {
            this.RectItems.Add(new RectItem { Height = 100, Width = 100, X = 0, Y = 0, Color = Brushes.DeepPink });
            this.RectItems.Add(new RectItem { Height = 50, Width = 50, X = 100, Y = 100, Color = Brushes.DeepSkyBlue });
        }

        private double _panelWidth = 100;
        private double _panelHeight = 100;
        public ObservableCollection<RectItem> RectItems { get; } = new ObservableCollection<RectItem>();


        public ICommand IncreaseSizeCommand => new RelayCommand(x =>
        {
            this.PanelHeight = 200;
            this.PanelWidth = 200;
        });

        public double PanelWidth {
            get { return _panelWidth; }
            set {
                if (value.Equals(_panelWidth)) return;
                _panelWidth = value;
                OnPropertyChanged();
            }
        }

        public double PanelHeight {
            get { return _panelHeight; }
            set {
                if (value.Equals(_panelHeight)) return;
                _panelHeight = value;
                OnPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

XAML

XAML

<StackPanel>
            <Button Content="Click me" Width="80" Height="20" Command="{Binding IncreaseSizeCommand}"/>
            <ItemsControl
                Grid.Row="0"
                ItemsSource="{Binding RectItems}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas Height="{Binding PanelHeight, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
                                Width="{Binding PanelWidth, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemContainerStyle>
                    <Style TargetType="ContentPresenter">
                        <Setter Property="Canvas.Left" Value="{Binding X}" />
                        <Setter Property="Canvas.Top" Value="{Binding Y}" />
                    </Style>
                </ItemsControl.ItemContainerStyle>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Rectangle
                            Width="{Binding Width}"
                            Height="{Binding Height}"
                            Fill="{Binding Color}" />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
</StackPanel>

Works as aspected. I've added some colors to do some visual highlighting and a command to change the size of the Canvas

按预期工作。我添加了一些颜色来做一些视觉突出显示和一个改变画布大小的命令