Zdravim. Mam Canvas v ktorom mam nejake Shape. Ked im nastavim hodnotu ZIndexu pred vlozenim do Canvasu tak sa zobrazuju podla toho aky maju ZIndex. Problem nastava vtedy ked im zmenim ZIndex niekedy neskor, vykresluju sa stale rovnako, ZIndex nema uz potom na to vplyv. Zaujimave vsak je, ze udalosti ako kliknutie myskou nad Shape tuto zmenu ZIndexu registruju spravne. ZIndex sa nastavy tak ako ma ale tvary sa stale vykresluju podla prvotneho ZIndexu. Tato chyba sa mi prejavuje len pod .NET 3.5 ak pouzijem 4 tak to funguje spravne. Neviete niekto ako odstranit tento bug.
Fórum › .NET
WPF ZIndex nefunguje spravne
Najlepsie asi bude ked ukazem screen toho co to robi.
Ten prvy screen znazornuje tu chybu pod .NET3.5 a ten druhy znazornuje to ako to ma ist. Staci ze prepnem projekt na NET4 a uz to ide ako ma.
Zdrojovy kod je v podtstate len jeden riadok a to:
Panel.SetZIndex(this as UIElement, 1);
Nastavujem vhodnu hodnotu pri udalostiach mysi. Pouzil som tiez Canvas.SetZIndex a vysledok je rovnaky.
<Window x:Class="test_zindex.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.Resources>
<Style TargetType="Rectangle">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Panel.ZIndex" Value="1"/>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<Canvas>
<Rectangle Fill="Orange" Width="100" Height="100" />
<Rectangle Fill="Green" Canvas.Top="50" Canvas.Left="50" Width="100" Height="100"/>
</Canvas>
</Grid>
</Window>
Visual Studio 2013 Ultimate, .NET 3.5, WPF, pusteno na Win 8.1 Pro v debug, po najeti na tverec se prenese dopredu (opakovane). Tak kde je teda ta chyba ? xD
btw. tam kde jede .NET 3.5 urcite jede i .NET 4 Client Profile
#4 p3can
Prisiel som na to, ze sa to chova uplne divne. Tie stvorce co vidis, tak to je moja vlastna trieda, ktora dedi od Shape. V triede mam definovane ContextMenu kde nastavujem tiez ZIndex a takto to funguje. Ale ak zavoiam metodu, ktora nastavuje ZIndex z vonku, tak to blbne.
#4 p3can
Tu je kod pre ContextMenu:
MouseRightButtonUp += new System.Windows.Input.MouseButtonEventHandler(myRectangleAndEllipse_MouseRightButtonUp);
}
void myRectangleAndEllipse_MouseRightButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
ContextMenu contextMenu = new ContextMenu();
MenuItem deleteMenuItem = new MenuItem();
deleteMenuItem.Header = "Delete";
deleteMenuItem.Click += deleteMenuItem_Click;
contextMenu.Items.Add(deleteMenuItem);
MenuItem zIndexUpMenuItem = new MenuItem();
zIndexUpMenuItem.Header = "ZIndex Up to: " + (Canvas.GetZIndex(this) + 1).ToString();
zIndexUpMenuItem.Click += zIndexUpMenuItem_Click;
contextMenu.Items.Add(zIndexUpMenuItem);
MenuItem zIndexDownMenuItem = new MenuItem();
zIndexDownMenuItem.Header = "ZIndex Down to: " + (Canvas.GetZIndex(this) - 1).ToString();
zIndexDownMenuItem.Click += zIndexDownMenuItem_Click;
contextMenu.Items.Add(zIndexDownMenuItem);
this.ContextMenu = contextMenu;
}
void zIndexDownMenuItem_Click(object sender, RoutedEventArgs e)
{
int zIndex = Canvas.GetZIndex(this);
if (zIndex > 0)
Canvas.SetZIndex(this, --zIndex);
}
<Window x:Class="test_zindex.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.Resources>
<ContextMenu x:Key="neco" >
<MenuItem Header="Front" Click="MenuItem_Click" />
<MenuItem Header="Behind" Click="MenuItem_Click_1" />
</ContextMenu>
<Style TargetType="Rectangle">
<Setter Property="ContextMenu" Value="{StaticResource neco}"/>
</Style>
</Grid.Resources>
<Canvas>
<Rectangle Fill="Orange" Width="100" Height="100" />
<Rectangle Fill="Green" Canvas.Top="50" Canvas.Left="50" Width="100" Height="100"/>
<Rectangle Fill="Gray" Canvas.Top="60" Canvas.Left="60" Width="100" Height="100"/>
<Rectangle Fill="Blue" Canvas.Top="70" Canvas.Left="70" Width="100" Height="100"/>
</Canvas>
</Grid>
</Window>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private int TopFront = 0;
private int TopBehind = 0;
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
var rec = ((sender as MenuItem).Parent as ContextMenu).PlacementTarget as Rectangle;
rec.SetValue(Panel.ZIndexProperty, ++TopFront);
}
private void MenuItem_Click_1(object sender, RoutedEventArgs e)
{
var rec = ((sender as MenuItem).Parent as ContextMenu).PlacementTarget as Rectangle;
rec.SetValue(Panel.ZIndexProperty, --TopBehind);
}
}
podle me mas spis problem v senderu nebo v tom ze si nedrzis globalni top a behind index.
#8 p3can
To si nemyslim, Keby ke chyba kdesi v kode tak to robi to iste aj pod .NET4 a nie len pod .NET3.5. Sender je urcite v poriadku, ono tu hodnotu ZIndexu nastavi spravne, aj po vycitani je ta hodnota nastavena tak ako ma byt, len v canvase sa to proste neprekresli tak ako ma. Aj udalost mysi reaguje na ten nastaveny ZIndex spravne.
Me ten muj kod jede normalne pod .Net 3.5. Podle me je chyby nekde u tebe. Chapu ze se to jinak chova pod 3.5 a jinak pod 4, ale podle me tam nekde pouzivas neco co neni nebo je jinak implementovane pod 3.5 nez ve 4.
Ahoj, jen takový dotaz. Při nastavování ZIndexu tomu obdélníku na prvním obrázku nastavuješ stejné ZIndexy i těm malým bílým? Minimálně ty bílé obdlélníky nebo čtverce by měli mít stejný ZIndex, ale vyšší než ten spodní zelený obdélník a nižší než ten výše.
#12 Zed_1
Nie, tie male biele stvorce su komponenty na resizovanie tvarov a oni maju pevne nastaveny ZIndex , ktory je najvacsi. Ziadny objekt, ktory sa kresli (stvorec, elipsa, polygon, obrazok atd.) nemoze mat nikdy vacsi ZIndex ako tie male stvorceky.
Původně jsem si myslel, že je chyba, že tem čtvereček je na vrchu. To jsem jen špatně pochopil.
Koukal jsem, že SP1 pro Framework 3.5 upravovali práci s ZIndexem. Ale předpokládám, že ten nainstalovaný máš.
Bohužel mám zkušenosti jen se Frameworkem 4.0, kde to pracuje správně i tobě.
Tak zatim mi to běží i na 3.5
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button Name="bt" Grid.Row="0">
<TextBlock Text="UP"></TextBlock>
</Button>
<Canvas x:Name="mainCanvas" Grid.Row="1">
<Rectangle Stroke="Black" Canvas.ZIndex="0" Width="30" Height="50" Fill="Beige" Canvas.Top="20" Canvas.Left="30"></Rectangle>
<Rectangle Stroke="Black" Canvas.ZIndex="1" Width="30" Height="50" Fill="Beige" Canvas.Top="30" Canvas.Left="40"></Rectangle>
<Rectangle Stroke="Black" Canvas.ZIndex="2" Width="30" Height="50" Fill="Beige" Canvas.Top="40" Canvas.Left="50"></Rectangle>
<Rectangle Stroke="Black" Canvas.ZIndex="3" Width="30" Height="50" Fill="Beige" Canvas.Top="50" Canvas.Left="60"></Rectangle>
<Rectangle Stroke="Black" Canvas.ZIndex="4" Width="30" Height="50" Fill="Beige" Canvas.Top="60" Canvas.Left="70"></Rectangle>
</Canvas>
</Grid>
Class MainWindow
Private elmsWithLowestZIndex As List(Of UIElement) = New List(Of UIElement)()
Private minZIndex As Integer = 0
Private maxZIndex As Integer = 100
Private Sub bt_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles bt.Click
For Each elm As UIElement In Me.mainCanvas.Children
Next
SetMinZIndex()
SetMaxZIndex()
SetElmsWithLowestZIndex()
SetHeirerZIndex()
End Sub
Private Sub SetMinZIndex()
minZIndex = maxZIndex
For Each elm As UIElement In Me.mainCanvas.Children
If Canvas.GetZIndex(elm) < minZIndex Then minZIndex = Canvas.GetZIndex(elm)
Next
End Sub
Private Sub SetMaxZIndex()
For Each elm As UIElement In Me.mainCanvas.Children
If Canvas.GetZIndex(elm) > maxZIndex Then maxZIndex = Canvas.GetZIndex(elm)
Next
End Sub
Private Sub SetElmsWithLowestZIndex()
elmsWithLowestZIndex.Clear()
For Each elm As UIElement In Me.mainCanvas.Children
If Canvas.GetZIndex(elm) = minZIndex Then elmsWithLowestZIndex.Add(elm)
Next
End Sub
Private Sub SetHeirerZIndex()
For Each elm In elmsWithLowestZIndex
Canvas.SetZIndex(elm, maxZIndex + 1)
Next
End Sub
End Class
#15 Zed_1
Mne to tiez bezi ked pouzivam rectangle! Ja ale mam vlastne triedy, ktore dedia od Shape a definujem si pozadovanu geometriu. Potom to proste nefunguje. ZIndex sa nastavi, aj ked ho vycitam je nastaveny spravne ale dany Shape sa neprekresli.
Přidal jsem nové tlačítko na vytvoření nového objektu a přídání do Canvas, a tím původním jsem stále schopen jeho ZIndex ovládat
Private Sub btNewItem_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles btNewItem.Click
SetMinZIndex()
SetMaxZIndex()
Dim ms As MyShape = New MyShape()
Me.mainCanvas.Children.Add(ms)
Canvas.SetZIndex(ms, maxZIndex + 1)
End Sub
Public Class MyShape
Inherits Shape
Protected Overrides ReadOnly Property DefiningGeometry As System.Windows.Media.Geometry
Get
Dim rct As Rect = New Rect(80, 70, 20, 50)
Dim ell As EllipseGeometry = New EllipseGeometry(rct)
Me.Stroke = Brushes.Black
Me.Fill = Brushes.Azure
Return ell
End Get
End Property
End Class
Ja mam tiez obdobne definovany vlastny Shape. Tiez si cez tlacitko v hlavnom okne pridam tento moj Shape do canvas.children. Na moj vlastny Shape nabindujem udalost MouseDown.
void myShape_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
if (_mode == Mode.PaintMode)
return;
unSelectAllShapes();
if (!(sender as ImyShape).isSelected())
(sender as ImyShape).Select();
else
(sender as ImyShape).UnSelect();
_selectedShapeForMoving = (sender as ImyShape);
_selectedShapes.Add(sender as ImyShape);
Canvas.SetZIndex(sender as UIElement, 105);
}
}
Tento sposob nefunguje. Obcas sa vsak stane ze zareaguje spravne. Pokial by som mal tuto udalost vytvorenu priamo v konstruktore mojho Shapu tak to ide. Ale ak tuto udalost vytvorim po vytvoreni objektu tak to blbne.
Teraz som zistil, ze ked robim Hit testovanie v udalosti Canvasu MouseDown tak to ide.
HitTestResult result = VisualTreeHelper.HitTest(canvas1, position);
if (result.VisualHit is myRectangleAndEllipse)
Canvas.SetZIndex(result.VisualHit as UIElement, 105);
Teraz som zistil, ze ked kod:
Canvas.SetZIndex(sender as UIElement, 105);
umiestnim nad unSelectAllShapes(); tak to ide. Zaujimave je, ze v tejto funkcii v podstate nic nerobim. Ako keby mu vadilo, ze sa zmeni nejaky atribut objektu.
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Podobná vlákna
PHPstorm nefunguje spravne, xubuntu — založil nord
Nefunguje mi správně volání "visibility" — založil tosik
Nefunguje správně $_SESSION - výpis proměnných z databáze — založil Fastmancz
Moderátoři diskuze