【问题标题】:Scroll/fit image with checkbox使用复选框滚动/适合图像
【发布时间】:2012-07-20 16:51:29
【问题描述】:

我想显示图像并添加复选框“适合屏幕” - 使图像适合可见区域。

为了使图像适合可见区域,我使用以下 xaml 片段:

<Image Source="{Binding Picture}" Stretch="Uniform"/>

要禁用拟合并添加滚动,我使用以下 xaml 片段:

<ScrollViewer VerticalScrollBarVisibility="Auto" 
              HorizontalScrollBarVisibility="Auto">
    <Image Source="{Binding Picture}" Stretch="None"/>
</ScrollViewer>

问题是如何将拟合和实际尺寸与滚动条结合起来,并使用复选框在两种状态之间切换?

更新:

问题在于代码Image/@Stretch=Uniform 的行为方式与&lt;ScrollViewer&gt; 中的Image/@Stretch=None 相同。在这两种情况下都可以看到滚动,并且图像以其实际大小显示。

详细说明。代码

<ScrollViewer VerticalScrollBarVisibility="Auto" 
              HorizontalScrollBarVisibility="Auto">
    <Image Source="{Binding Picture}" Stretch="Uniform" />
</ScrollViewer>

工作方式与

相同
<ScrollViewer VerticalScrollBarVisibility="Auto" 
              HorizontalScrollBarVisibility="Auto">
    <Image Source="{Binding Picture}" Stretch="None" />
</ScrollViewer>

【问题讨论】:

    标签: wpf xaml layout scrollview


    【解决方案1】:

    创建一个值转换器,将复选框的选中状态转换为Stretch.UnfiormStretch.None

    public class StretchValueConverter : IValueConverter
    {
      public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
      {
        return (bool)value ? Stretch.Uniform : Stretch.None;
      }
    
      public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
      {
        return value.Equals(Stretch.Uniform);
      }
    
    }
    

    然后在您的 XAML 中,您可以执行以下操作:

    <Window.Resources>
    
      <local:StretchValueConverter x:Key="StretchValueConverter" />
    
    </Window.Resources>
    
    <CheckBox x:Name="FitToScreen" />
    
    <ScrollViewer VerticalScrollBarVisibility="Auto" 
                  HorizontalScrollBarVisibility="Auto">
        <Image Source="{Binding Picture}" Stretch="{Binding ElementName=FitToScreen Converter={StaticResource StretchValueConverter}, Path=Checked"/>
    </ScrollViewer>
    

    更新

    您还需要将HorizontalScrollBarVisibilityVerticalScrollBarVisibilty 设置为Disabled 以强制滚动查看器的内容不超出边界。您可以使用另一个转换器或样式来监听 Checkbox.Checked 属性。

    <Window x:Class="Overflow.Examples.Wpf.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.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
    
            <CheckBox x:Name="FitToScreen" Grid.Row="0" Content="Fit to screen" />
    
            <ScrollViewer Grid.Row="1">
                <Image Source="{Binding Picture}">
                    <Image.Style>
                        <Style TargetType="Image">
                            <Setter Property="Stretch" Value="None" />
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding ElementName=FitToScreen, Path=IsChecked}" Value="True">
                                    <Setter Property="Stretch" Value="Uniform" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Image.Style>
                </Image>
    
                <ScrollViewer.Style>
                    <Style TargetType="ScrollViewer">
                        <Setter Property="HorizontalScrollBarVisibility" Value="Auto" />
                        <Setter Property="VerticalScrollBarVisibility" Value="Auto" />
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding ElementName=FitToScreen, Path=IsChecked}" Value="True">
                                <Setter Property="HorizontalScrollBarVisibility" Value="Disabled" />
                                <Setter Property="VerticalScrollBarVisibility" Value="Disabled" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </ScrollViewer.Style>
            </ScrollViewer>
        </Grid>
    </Window>
    

    【讨论】:

    • 这无济于事,我对问题进行了澄清
    • SourceName="FitToScreen" 在此处不起作用,出现错误消息:“错误 MC4110:无法在 Style.Triggers 部分中设置 SourceName 属性。第 18 行位置 59。” (social.msdn.microsoft.com/Forums/en-US/wpf/thread/…)
    • 不知道这个限制,我发誓我以前曾以这种方式使用过 SourceName。唉,我还没有测试过样品,但老实说认为它会起作用。毕竟你可能必须实现一个转换器。当我有机会时,我会看看我是否可以将一个工作示例放在一起。
    • 刚刚更新了我的答案以使用绑定到CheckBoxDataTriggers。仍然没有时间对此进行测试,但我不明白为什么它不起作用。
    【解决方案2】:

    您只能使用应用于图像样式的触发器在 xaml 中执行此操作 -

    <CheckBox x:Name="FitToScreen" />    
        <ScrollViewer VerticalScrollBarVisibility="Auto" 
                      HorizontalScrollBarVisibility="Auto">
            <Image Source="{Binding Picture}">
               <Image.Style>
                  <Style TargetType="Image">
                     <Setter Property="Stretch" Value="None"/>
                     <Style.Triggers>
                         <Trigger Property="IsChecked" SourceName="FitToScreen" Value="True">
                            <Setter Property="Stretch" Value="Uniform"/>
                         </Trigger>
                     </Style.Triggers>
                  </Style>
               </Image.Style>
            </Image>
        </ScrollViewer>
    

    更新

    作为一种解决方法,您可以将两个图像放在一个网格中,并根据复选框选中状态来使用其可见性,如下所示 -

    <CheckBox x:Name="FitToScreen"/> 
    <Grid>
      <Grid.Resources>
         <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
      </Grid.Resources>
      <Image Source="{Binding Picture}" Stretch="Uniform"
             Visibilty="{Binding IsChecked, ElementName=FitToScreen, Converter={StaticResource BooleanToVisibilityConverter}}"/>
      <ScrollViewer VerticalScrollBarVisibility="Auto" 
                  HorizontalScrollBarVisibility="Auto">
        <Image Source="{Binding Picture}" Stretch="None"/>
      <ScrollViewer.Style>
        <Style TargetType="Image">
           <Setter Property="Visibility" Value="Visible"/>
             <Style.Triggers>
                <Trigger Property="IsChecked" SourceName="FitToScreen" Value="True">
                   <Setter Property="Visibility" Value="Collapsed"/>
                </Trigger>
             </Style.Triggers>
         </Style>
      </ScrollViewer.Style>
      </ScrollViewer>
    </Grid>
    

    【讨论】:

    • 这无济于事,我对问题进行了澄清。并感谢 xaml 的简洁代码示例!
    • 我也考虑过这种方法,但@sellmeadog 提供了简洁的更新。无论如何,非常感谢!
    • SourceName 在这里不起作用(参考:social.msdn.microsoft.com/Forums/en-US/wpf/thread/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多