1

私はWPFが初めてです。ボタンクリックでキャンバスに長方形を次々と追加しています。TextBox から特定の四角形の高さを設定すると。子長方形に重なっています。

例えば:。 & の高さを設定したときに 3 つの長方形がある場合。次に、子は 2 番目の Rectangle の後に表示される必要があり、3 番目の Rectangle に重なってはなりません。出来ますか?Height=100Width=200Second Rectangle to 150Rectangle

static int val=0;
List<UIElement> itemstoremove = new List<UIElement>();
private void BtnAdd_Click(object sender, RoutedEventArgs e)
        {

            int heigt = 0;
            int wegt = 0;
             if (!string.IsNullOrEmpty(txtHeight.Text) && !string.IsNullOrEmpty(txtWidth.Text))
            {
                heigt = int.Parse(txtHeight.Text);
                wegt = int.Parse(txtWidth.Text);
            }
            rect = new Rectangle();
            rect.Stroke = Brushes.Red;
            rect.StrokeThickness = 2;
            rect.Height = heigt;
            rect.Width = wegt;
            Canvas.SetLeft(rect, 10);
            Canvas.SetTop(rect, (rect.Height) * val);
            rect.Tag = val;
            canvasboard.Children.Add(rect);
            val = val + 1;
            //canvasboard is Canvas object
            foreach (UIElement ui in canvasboard.Children)
            {
                if (ui.GetType() == typeof(Rectangle))
                {
                    itemstoremove.Add(ui);
                }
            }
        }

高さと幅を変更するには:

private void BtnModify_Click(object sender, RoutedEventArgs e)
        {
            int heigt = 0;
            int wegt = 0;
            if (!string.IsNullOrEmpty(txtHeight.Text) && !string.IsNullOrEmpty(txtWidth.Text))
            {
                heigt = int.Parse(txtHeight.Text);
                wegt = int.Parse(txtWidth.Text);
            }
            Rectangle rectToRemove;

            foreach (UIElement ui in itemstoremove)
            {
                if (ui.GetType() == typeof(Rectangle) && ((Rectangle)ui).Tag.ToString() == txtModifyRect.Text)
                {
                    rectToRemove = ui as Rectangle;
                    //itemstoremove.Remove(rectToRemove);
                    rectToRemove.Height = heigt;
                    rectToRemove.Width = wegt;
                    //canvasboard.Children.Remove(rectToRemove);
                    break;
                }
            }  
        }

これはうまくいきます。お互いの重なりを防ぎたいだけRectangleで、自動調整で次々と現れなければなりません。

助けて感謝!

4

4 に答える 4

1

具体的にする必要がありCanvasますか..?純粋な WPF/Desktop でも、これを完全に自動的に実行できるレイアウト コンポーネントがいくつかあります。

コンポーネントを次々に「積み重ねる」動作は、まさにStackPanelクラス/コンポーネント/コントロールが行うことです:

<StackPanel x:Name="stacker" Orientation="Vertical">
    <Rectangle Width="30" Height="100" Background="Green" />
    <Rectangle Width="10" Height="50" Background="Blue" />
    <Rectangle Width="20" Height="80" Background="Red" Margin="5,10" />
</StackPanel>

異なるHeights. Orientation=VerticalStackPanel のデフォルトの動作は、そのように配置することであるため、指定する必要はありませんでした。必要に応じて水平に切り替えることができ、その後、それらに従ってスタックされますWidths。3 番目の長方形のように、 ie を使用して微調整し、余分な間隔を追加することもできますMargin

コードで行う必要がある場合は、StackPanelnamedstackerが最適です。新しい要素を動的に追加でき、XAML で定義された子の場合と同じように、追加された要素が 1 つずつ下に配置されます。

StackPanel を使用すると、さらに多くのことが得られます。StackPanel はその子を観察します。子を配置した後、子の高さ/幅を変更すると、StackPanel はすぐに位置を調整して、重ならないようにします (子を小さくすると、子が大きくなり、子を大きくすると、それらが圧迫されます。など)が展開されます。

本当に を使用したい場合はCanvas、新しいアイテムを追加するときに、キャンバスに保存されているすべての既存のアイテムをループし、それらの高さを合計して、新しいアイテムの Y 位置を設定する必要があります。アイテムに正確にその合計。そうすれば、最後の要素の下に正確に表示されます。それが最も明白な方法です。ただし、余白、間隔、および Canvas に発生する可能性のあるその他の細かい部分は考慮されません。

あまり明白ではありませんが、より適切な方法は、高さを何度も合計するのではなく、最下部の既存のアイテムに従って新しいアイテムを配置することです。結局のところ、すべての古いアイテムは適切に配置されていますよね? しかし、どういうbottommost意味ですか?上部近くに配置された背の高いアイテムが、中央にあるそれほど高くないアイテムよりも下に広がることがあります。したがって、bottommostは を意味するのではなく、the item with maximum Y positionが最も遠いアイテムを意味します。そう:Bottommaximum Y+Height

  • 既存のアイテムをループする
  • Size.Height+Position.Bottom最大のアイテムを見つける
  • Position.Y新しいアイテムの をその値に設定します

これで、StackPanel とほぼ同じ結果が得られますが、効果は 1 回限りです。後でいくつかの要素の高さを変更する場合は、すべての位置を再計算してすべての位置を調整する必要があります.. (*)

編集: (*) 正確には覚えていませんが、X/Y/Bottom プロパティが DependencyProperty の場合、位置を自動的に制御するために Bindings を使用することもできます。キャンバス上で行うのはとても楽しいことかもしれません。Y後者の要素の を前者の にバインドしてみBottomてください。すべて魔法のようにレイアウトされ、移動/サイズ変更されたときに自動的に更新されるはずです。それでも、まずは StackPanel を試してみてください。

于 2013-07-11T12:57:20.483 に答える