#wpf #image
#wpf #изображение
Вопрос:
У меня есть приложение WPF, которое основано на нескольких сетках. Пока все работает так, как ожидалось. Приложение показывает какую-то панель инструментов вверху и элемент управления изображением в центре / внизу. Когда я изменяю размер окна, изменяется и размер элемента изображения, что совершенно нормально.
Теперь, когда я устанавливаю ImageSource в качестве элемента управления изображением, а изображение большое (например, по вертикали), это приведет к изменению размера всего окна также по вертикали.
Как я могу разрешить пользователю изменять размер окна (включая изменение размера изображения), но НЕ разрешать операцию изменения размера при загрузке изображения в элемент управления изображением?
<Window x:Class="GrafAoiKyErrorViewer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ignore="http://www.galasoft.ch/ignore"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:command="http://www.galasoft.ch/mvvmlight"
xmlns:grafAoiKyErrorViewer="clr-namespace:GrafAoiKyErrorViewer"
mc:Ignorable="d ignore"
ResizeMode="CanResizeWithGrip"
SizeToContent="WidthAndHeight"
Title="Graf AOI KY Error Viewer"
MinWidth="600"
DataContext="{Binding Main, Source={StaticResource Locator}}"
Icon="Images/AnalyzeTrace_16x.png" MinHeight="800"
>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<command:EventToCommand Command="{Binding WindowLoadedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Window.InputBindings>
<KeyBinding Command="{Binding Path=SelectNextCommand}" Gesture="F2" />
<KeyBinding Command="{Binding Path=SelectPreviousCommand}" Gesture="F1" />
</Window.InputBindings>
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
<grafAoiKyErrorViewer:ErrorClassToStringConverter x:Key="ErrorClassToStringConverter" />
</ResourceDictionary>
</Window.Resources>
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Margin="3">Datenbank</Label>
<ComboBox Grid.Row="0" Grid.Column="1" Margin="3" MinWidth="400" ItemsSource="{Binding AoiDatabaseCollection}" DisplayMemberPath="DisplayString" SelectedValue="{Binding AoiDatabaseSelected}" />
<Label Grid.Row="1" Grid.Column="0" Margin="3">Projekt</Label>
<ComboBox Grid.Row="1" Grid.Column="1" Margin="3" MinWidth="400" ItemsSource="{Binding AoiProjectCollection}" DisplayMemberPath="Name" SelectedValue="{Binding AoiProjectSelected}" />
<Label Grid.Row="2" Grid.Column="0" Margin="3">Lot</Label>
<ComboBox Grid.Row="2" Grid.Column="1" Margin="3" MinWidth="400" ItemsSource="{Binding AoiLotCollection}" DisplayMemberPath="Name" SelectedValue="{Binding AoiLotSelected}" />
<Grid Margin="10" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<ListView Grid.Column="0" Grid.Row="0" Margin="3" ItemsSource="{Binding ErrorClassCollection}" Height="200" SelectionMode="Single" MinWidth="200">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsSelected}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding Item, Converter={StaticResource ErrorClassToStringConverter}}" Header="Fehlerklasse" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
<StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="0">
<Button Margin="3" Padding="3" Command="{Binding ModifySelectionErrorClassAllOnCommand}">Alle Ein</Button>
<Button Margin="3" Padding="3" Command="{Binding ModifySelectionErrorClassAllOffCommand}">Alle Aus</Button>
<Button Margin="3" Padding="3" Command="{Binding ModifySelectionErrorClassRealErrorsOnlyCommand}">Echte Fehler</Button>
</StackPanel>
<ListView Grid.Column="1" Grid.Row="0" Margin="3" ItemsSource="{Binding PositionCollection}" Height="200" SelectionMode="Single" MinWidth="200">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsSelected}" />
<!--<CheckBox IsChecked="{Binding IsSelected}" Command="{Binding DataContext.FailureSelectionChangedCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}}" />-->
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding Item}" Header="Position" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
<StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="1">
<Button Margin="3" Padding="3" Command="{Binding ModifySelectionPositionAllOnCommand}">Alle Ein</Button>
<Button Margin="3" Padding="3" Command="{Binding ModifySelectionPositionAllOffCommand}">Alle Aus</Button>
</StackPanel>
<ListView Grid.Column="2" Grid.Row="0" Margin="3" ItemsSource="{Binding ArticleCollection}" Height="200" SelectionMode="Single" MinWidth="200">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsSelected}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding Item}" Header="Artikel" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
<StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="2">
<Button Margin="3" Padding="3" Command="{Binding ModifySelectionArticleAllOnCommand}">Alle Ein</Button>
<Button Margin="3" Padding="3" Command="{Binding ModifySelectionArticleAllOffCommand}">Alle Aus</Button>
</StackPanel>
<ListView Grid.Column="3" Grid.Row="0" Margin="3" ItemsSource="{Binding PartTypeCollection}" Height="200" SelectionMode="Single" MinWidth="200">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsSelected}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding Item}" Header="Bauform" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
<StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="3">
<Button Margin="3" Padding="3" Command="{Binding ModifySelectionPartTypeAllOnCommand}">Alle Ein</Button>
<Button Margin="3" Padding="3" Command="{Binding ModifySelectionPartTypeAllOffCommand}">Alle Aus</Button>
</StackPanel>
</Grid>
<Button Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="3" Margin="3" Padding="3" HorizontalAlignment="Left" Command="{Binding FailureSelectionChangedCommand}">Aktualisieren</Button>
<Grid Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid MinWidth="200">
<!-- DUMMY GRID -->
</Grid>
<Image Grid.Row="0" Grid.Column="1" Source="{Binding CurrentFailureItem.KyAoiFailureImage.Image2DData}" Stretch="Uniform" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></Image>
<!--<Viewbox HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
</Viewbox>-->
<!--<Border BorderThickness="1" BorderBrush="Black" >
</Border>-->
<Grid Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" MinWidth="100" Margin="3" Padding="3" VerticalAlignment="Center" Command="{Binding SelectPreviousCommand}">Previous</Button>
<TextBlock Grid.Column="1" Margin="3" Padding="3" HorizontalAlignment="Stretch" TextAlignment="Center">
<Run Text="{Binding SelectedFailureItemIndexDisplay, Mode=OneWay}"></Run>
<Run Text=" / "></Run>
<Run Text="{Binding TotalFailureItemIndex, Mode=OneWay}"></Run>
</TextBlock>
<Button Grid.Column="2" MinWidth="100" Margin="3" Padding="3" VerticalAlignment="Center" Command="{Binding SelectNextCommand}">Next</Button>
</Grid>
<StackPanel Grid.Row="0" Grid.Column="2" Orientation="Vertical" VerticalAlignment="Center" Margin="3" MinWidth="200">
<TextBlock Text="{Binding CurrentFailureItem.Position}" FontSize="10" FontWeight="Bold"></TextBlock>
<TextBlock Text="{Binding CurrentFailureItem.Article}" FontSize="10" FontWeight="Bold"></TextBlock>
<TextBlock Text="{Binding CurrentFailureItem.PartType}" FontSize="10" FontWeight="Bold"></TextBlock>
<TextBlock Text="{Binding CurrentFailureItem.ErrorClass}" FontSize="10" FontWeight="Bold"></TextBlock>
</StackPanel>
</Grid>
</Grid>
Комментарии:
1. пожалуйста, поделитесь своим XAML
2. Прикрепил его к основному сообщению. Элемент управления изображением находится внизу (это вообще единственный элемент изображения).
Ответ №1:
То, что вы видите, на самом деле является предполагаемым поведением элемента управления, однако, чтобы устранить эту проблему, найдите эту строку в своем коде:
<Grid Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="3" >
и замените его этим:
<Grid Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="3" MaxHeight="100">
при установке maxHeight на разумное значение
РЕДАКТИРОВАТЬ: Хорошо, поймите, в этом случае замените изображение сеткой и используйте его фон:
<Grid Grid.Row="0" Grid.Column="1">
<Grid.Background>
<ImageBrush ImageSource="{Binding CurrentFailureItem.KyAoiFailureImage.Image2DData}" Stretch="Uniform"></ImageBrush>
</Grid.Background>
</Grid>
Комментарии:
1. Да, но это именно то, чего я НЕ хочу. Я хочу, чтобы пользователь мог изменять размер окна (тем самым изменяя размер элемента управления изображением в обоих направлениях), но я не хочу, чтобы элемент управления изображением изменял размер пользовательского интерфейса (наоборот)
2. Обновлен ответ
3. Это кажется довольно банальным, но работает как шарм. Спасибо!
4. рад, что смог помочь! действительно, кажется, что это правильное решение вашей проблемы, но чтобы избежать этого, вам пришлось бы не изменять размер окна, что возможно только путем полного отключения функции изменения размера или путем самостоятельной обработки событий, оба других метода либо плохи, либо не то, что вы ищете
Ответ №2:
Попробуйте вложить свой элемент управления изображением в Viewbox:
<Viewbox>
<Image ImageSource="{Binding MyImage"/>
</Viewbox>
Возможно, вам придется повозиться с атрибутом Viewbox Stretch
(я всегда забываю, какой из них что делает, но обычно вы можете заставить его делать то, что вы хотите, методом проб и ошибок).
Комментарии:
1. Я пробовал использовать всевозможные варианты центра / растяжения как для Viewbox, так и для изображения, но результат всегда был одинаковым. Я также попробовал свойство StretchDirection=DownOnly для элемента управления изображением, но это также не дало ожидаемого результата