如何根据子<wpf> </wpf>调整画布大小

时间:2014-12-13 14:36:35

标签: wpf canvas

我写

 <TabItem Header="Map">
     <Grid Background="#FFE5E5E5" Margin="0,0,0,0">
      <ScrollViewer x:Name="mapScroll" HorizontalAlignment="Left" Height="248" Margin="10,10,0,0" VerticalAlignment="Top" Width="467" HorizontalScrollBarVisibility="Auto"/>
     </Grid>
    </TabItem>

并添加代码

Canvas ca=new Canvas();
 mapScroll.Content=ca;

并添加

 Button btnTest1 = new Button();
     btnTest1.Width = 100;
     btnTest1.Height = 150;
     Canvas.SetLeft(btnTest1, 200);
     Canvas.SetTop(btnTest1, 200);
ca.Children.Add(btnTest1);

按钮位于画布的边界区域。 按钮的一侧不可见,并且未激活滚动条。 我想调整画布大小以包含完整按钮,因此应该激活滚动条... ScollViewer的大小相同。

我如何调整画布大小,因此滚动条必须激活。

1 个答案:

答案 0 :(得分:0)

我认为大量的代码会让大多数人失望,所以我在开始时发布了解决方案here。 我的概念是根据Canvas.Children.Count制作Canight of Canvas。每次收集更改时,这都会改变Canvas的高度。但不幸的是,Children.Count不是依赖属性,因此它不反映任何变化。我使用ChildrenCount属性实现了自定义画布,让我们了解更改。另一个问题是,Canvas没有提供任何事件来向其子项添加项目,因此我被允许从基类重写OnVisualChildrenChanged事件。我依靠你对这段代码的理解。

public class CustomCanvas : Canvas, INotifyPropertyChanged
{
    private int childrenCount;

    public int ChildrenCount
    {
        get { return childrenCount; }
        set
        {
            childrenCount = value;
            OnPropertyChanged();
        }
    }

    protected override void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved)
    {
        if (visualAdded == null)
            --ChildrenCount;
        else
            ++ChildrenCount;
        base.OnVisualChildrenChanged(visualAdded, visualRemoved);
    }

    public void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

XAML:

 <StackPanel>
    <StackPanel.Resources>
        <local:ChildrenCountToHeightConverter x:Key="ChildrenCountToHeightConverter"/>
    </StackPanel.Resources>
    <ScrollViewer HorizontalAlignment="Left" Height="248" Margin="10,10,0,0" VerticalAlignment="Top" Width="467"
                  HorizontalScrollBarVisibility="Auto"
          VerticalScrollBarVisibility="Auto">
        <local:CustomCanvas x:Name="CustomCanvas" MaxHeight="1555">
            <local:CustomCanvas.Height>
                <MultiBinding Converter="{StaticResource ChildrenCountToHeightConverter}">
                    <Binding RelativeSource="{RelativeSource Self}" Path="(local:CustomCanvas.ChildrenCount)"/>
                    <Binding RelativeSource="{RelativeSource Self}" Path="(local:CustomCanvas.Children)"/>
                </MultiBinding>
            </local:CustomCanvas.Height>
        </local:CustomCanvas>
    </ScrollViewer>
    <Button Content="dodaj" Click="ButtonBase_OnClick"/>
</StackPanel>


 private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        Button btnTest1 = new Button();
        btnTest1.Width = 100;
        btnTest1.Height = 150;
        Canvas.SetLeft(btnTest1, 200);
        Canvas.SetTop(btnTest1, 200);
        CustomCanvas.Children.Add(btnTest1);
    }


public class ChildrenCountToHeightConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var childrenNumber = System.Convert.ToInt32(values[0].ToString());
        if (childrenNumber == 0)
            return 0;
        var children = (UIElementCollection)values[1];
        var y = children.OfType<Button>().Max(x => Canvas.GetTop(x));
        return y + children.OfType<Button>().First(x => Canvas.GetTop(x) == y).Height + 50;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

我确信它需要一些改变,但现在它有效。一旦我添加按钮画布'高度根据放在底部的按钮进行调整。