如何根据子对象调整画布大小<;wpf>;
我写如何根据子对象调整画布大小<;wpf>;,wpf,canvas,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" HorizontalScrollBarVis
<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>
加
Button btnTest1 = new Button();
btnTest1.Width = 100;
btnTest1.Height = 150;
Canvas.SetLeft(btnTest1, 200);
Canvas.SetTop(btnTest1, 200);
ca.Children.Add(btnTest1);
按钮位于画布的边界区域。
按钮的侧面不可见,滚动条未激活。
我想调整画布大小,以包括完整的按钮,所以滚动条应该被激活。。。
ScollViewer的大小相同
如何调整画布的大小,以便滚动条必须激活。我假设大量的代码会让大多数人望而却步,所以我在开始时发布解决方案。 我的概念是使画布的高度取决于Canvas.Children.Count。这将在每次集合更改时更改画布的高度。但不幸的是,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:
public类ChildrenCountToHeightConverter:IMultiValueConverter
{
公共对象转换(对象[]值,类型targetType,对象参数,System.Globalization.CultureInfo区域性)
{
var childrenNumber=System.Convert.ToInt32(值[0].ToString());
if(childrenNumber==0)
返回0;
var children=(UIElementCollection)值[1];
var y=children.OfType().Max(x=>Canvas.GetTop(x));
返回y+children.OfType().First(x=>Canvas.GetTop(x)==y)。高度+50;
}
公共对象[]转换回(对象值,类型[]目标类型,对象参数,System.Globalization.CultureInfo区域性)
{
抛出新的NotImplementedException();
}
}
我确信它需要一些改变,但现在它起作用了。添加按钮后,画布的高度将根据底部的按钮进行调整。可能与“谢谢”重复。这段代码运行得很好。但我必须添加图像和文本块,所以我更改了“children.OfType()”->“children.OfType()”,并将图像添加到CustomCanvas boundary like按钮中(暂时仅添加图像),然后就不起作用了。如何适应图像和文本块?我想不仅适应垂直对齐,还适应水平对齐。如果您想要许多不同类型的对象,只需添加其基本类,如FrameworkElement,而不是Image或Button。如果您想要宽度,您需要添加与高度相同的绑定,但需要添加另一个转换器,您将在其中查找Canvas.GetLeft(obj)。如果有用,请将其标记为answear。
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;
}
<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();
}
}