Как наложить холст для представления слоев типов объектов, чтобы я мог показывать/скрывать определенные слои?
Поэтому, честно говоря, я уже ставил этот вопрос на StackOverflow, не получая никаких особенно полезных ответов, я признаю, что могут быть, возможно, лучшие способы структурирования кода, но я хочу частично понять ограничения объекта Canvas (если действительно это проблема), и поскольку было два варианта:
голоса на SO предполагают использование "ItemControls as layers", почему этот метод может быть лучшим решением.
Итак, я намеревался наложить несколько холстов, от 4 до 6 слоев, поверх большого изображения, чтобы я мог установить все объекты в данном холсте как видимые или невидимые с простотой процедуры показа или скрытия в классе слоев. UpdateLayers просто имеет набор вызовов для каждого слоя.Обновление(). В случае слоя settlementNames может показаться, что код обновления не выполняет свою работу. Это должно работать так;
private void ShowCities_Click(object sender, RoutedEventArgs e) { UpdateLayers(); settlements.Show(Settlements); settlementNames.Show(SettlementNames); } public void Show(Canvas canvas) { canvas.Visibility = Visibility.Visible; }
Это прекрасно работало с первым холстом, содержащим растровые изображения размером с иконку в ZIndex 1 (большое изображение по существу является фоном с ZIndex 0). Когда я попытался добавить еще один холст в ZIndex 2, код прошел, как и ожидалось, но не показал содержимое. На этот раз содержимое представляет собой набор текстовых блоков.
Свойство AssociatedCanvas в коде было проверено и является правильным экземпляром Canvas, который был заложен в главном окне XAML.
public void Update(string layerSelectSqlQuery, LayerType layerType) { DataTable layerDataTable = null; int x = -1; int y = -1; string label; using (MySqlClientWrapper db = new MySqlClientWrapper("Server = localhost; Database = tribes;Uid = root;Pwd = xxxxxxxxx;")) { // TODO add population column - and filter to those settlements considered cities. layerDataTable = db.GetDataTable(layerSelectSqlQuery); } AssociatedCanvas.Children.Clear(); foreach (DataRow dataRow in layerDataTable.Rows) { x = (int)dataRow["MapX"]; y = (int)dataRow["MapY"]; label = dataRow["Name"].ToString(); if (x != -1 && y != -1) { switch (layerType) { case LayerType.Settlements: DrawBitmapImage(x, y); break; case LayerType.SettlementNames: WriteLabel(x, y, label, Color.FromRgb(0, 0, 0)); break; case LayerType.Units: break; case LayerType.UnitNames: break; default: break; } } } } Public void WriteLabel(int x, int y, string text, Color color) { TextBlock textBlock = new TextBlock(); textBlock.Text = text; textBlock.Foreground = new SolidColorBrush(color); Canvas.SetLeft(textBlock, x); Canvas.SetTop(textBlock, y); AssociatedCanvas.Children.Add(textBlock); }
XAML выглядит примерно так:
<Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <!--<Slider Grid.Column="0" Orientation="Vertical" HorizontalAlignment="Left" Minimum="1" x:Name="slider" />--> <ScrollViewer Name="mapScroller" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"> <Grid Name="grid" RenderTransformOrigin="0.5,0.5"> <Grid.LayoutTransform> <TransformGroup> <ScaleTransform x:Name="scaleTransform" /> </TransformGroup> </Grid.LayoutTransform> <Viewbox Grid.Column="0" Grid.Row="0" > <Image x:Name="MainMap" UseLayoutRounding="True" Stretch="Fill" HorizontalAlignment="Center" VerticalAlignment="Center" MouseLeftButtonUp="MainMap_MouseLeftButtonUp" Source="{Binding MainTerrainMap}"></Image> </Viewbox> <Canvas x:Name="Settlements" Panel.ZIndex="1" /> <Canvas x:Name="SettlementNames" Panel.ZIndex="2" > </Canvas> </Grid> </ScrollViewer> </Grid>
Что я уже пробовал:
Я задавался вопросом, является ли размер изображения и, следовательно, холста проблемой, 21600 x 10800 пикселей, потому что после замены этого изображения на гораздо меньшее изображение 400 x 400, меньшее, чем обычно было бы у ScrollViewer, функция show hide для второго холста ("имена поселений") работала . Но голый в уме я мог бы показать/скрыть Нижний холст ZOrder ("поселения") без проблем. Может быть, это ограничение памяти?