Wpf 如何使用xaml触发器或样式选择器根据可用空间调整控件大小
我正在尝试制作一个按钮,根据可用空间大小改变其布局,使其变得更小 这些按钮将始终有一个stackpanel,其中包含图像和文本块。我的目标是能够为这些按钮定义3-4种不同的样式,每种样式都会产生不同的按钮大小 对于每个按钮图像,我有4个版本,如果图像的分辨率不同。16、32、48和64。这些图像存储在不同的文件夹中;i、 e.Images\Icons\16\Add.png和Images\Icons\32\Add.png。这两张图片都一样,只是大小不同。我选择使用多个尺寸,因为我发现只有一个图像并缩放其尺寸会导致图像变得相当模糊 为了方便选择不同大小的图像,我创建了一个转换器,用于绑定图像源:Wpf 如何使用xaml触发器或样式选择器根据可用空间调整控件大小,wpf,xaml,Wpf,Xaml,我正在尝试制作一个按钮,根据可用空间大小改变其布局,使其变得更小 这些按钮将始终有一个stackpanel,其中包含图像和文本块。我的目标是能够为这些按钮定义3-4种不同的样式,每种样式都会产生不同的按钮大小 对于每个按钮图像,我有4个版本,如果图像的分辨率不同。16、32、48和64。这些图像存储在不同的文件夹中;i、 e.Images\Icons\16\Add.png和Images\Icons\32\Add.png。这两张图片都一样,只是大小不同。我选择使用多个尺寸,因为我发现只有一个图像并
class ImagePathResolutionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Image sender = (Image)value;
int imageSize = (parameter != null) ? (parameter is int) ? (int)parameter : (parameter is string) ? Int32.Parse((string)parameter) : 16 : 16;
Uri returnImage = new Uri(String.Format(@"Images\Icons\{0}\{1}", imageSize, sender.Tag as string), UriKind.Relative);
return returnImage;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
绑定如下所示:
<Setter Property="Source"
Value="{Binding .,
Converter={StaticResource ImagePathResolutionConverter},
RelativeSource={RelativeSource Self},
ConverterParameter='16'}"
/>
使用此设置意味着我可以将16、32、48或64传递给ConverterParameter,并返回相应的映像路径
现在,对于这个例子,我有两种风格
大:
。。。又小
<!-- Small Button Container Style -->
<Style TargetType="Button" x:Key="MultiResButton_Small">
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Top" />
<Style.Resources>
<!-- Button.StackPanel Style -->
<Style TargetType="StackPanel">
<Setter Property="Orientation" Value="Horizontal" />
<Style.Resources>
<!-- Button.StackPanel.Image Style -->
<Style TargetType="Image">
<Setter Property="Stretch" Value="None" />
<Setter Property="Margin" Value="5 2" />
<Setter Property="Source" Value="{Binding ., Converter={StaticResource ImagePathResolutionConverter}, RelativeSource={RelativeSource Self}, ConverterParameter='16'}" />
</Style>
<!-- Button.StackPanel.TextBlock Style -->
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="0 5 2 5" />
</Style>
</Style.Resources>
</Style>
</Style.Resources>
</Style>
其中一个按钮的XAML为:
<Button Style="{StaticResource ResourceKey=MultiResButton_Big}">
<StackPanel>
<Image Tag="Multi.png" />
<TextBlock Text="Button Text" />
</StackPanel>
</Button>
目前,我可以设置一个按钮或这些,结果是一个大或小按钮。现在我只需要弄清楚如何决定何时使用哪个,以及如何通过编程来实现
在我看来,我有两个选择:将两种样式合并为一种并使用某种触发器,或者创建一个样式选择器类,让它选择要使用的样式
我的问题是,我不知道如何通过编程确定使用哪种风格。我发现当按下按钮超出容器的可见范围时,“RenderSize.Width”被设置为0。我的问题是,当5个按钮位于容器的可见边界之外时,将5设置为使用较小的样式将没有帮助。。。我还必须为其他可见按钮使用较小的尺寸,以便为超出边界的5个按钮“腾出空间”
我很乐意为容器中的所有按钮设置样式。。。当一个按钮renderSize.Width=0时,将所有同级按钮的样式尺寸降低到更低
我所尝试的是可能的吗?我是否必须创建自定义容器以覆盖所有子控件的呈现?我宁愿避免,如果我能。。。但我看不到任何其他可能的方法
例如,打开Word或Excel 2007/2010,慢慢调整窗口大小,使其变小。当你这么做时,核糖上的按钮会“收缩”以腾出更多的空间
如果您能考虑一下我是否从正确的方向来处理这个问题,我将不胜感激。您可以使用第二个转换器来绑定样式 创建一个IMultiValueConverter,它接受两个值,ActualWidth和计算将基于的元素(在我的示例中,我使用的是Window): 然后,更改按钮以使用转换器选择样式:
<Button>
<Button.Style>
<MultiBinding Converter="{StaticResource ImageButtonStyleSelectorConverter}"
FallbackValue="{StaticResource MultiResButton_Big}">
<Binding RelativeSource="{RelativeSource AncestorType=Window, Mode=FindAncestor}" Path="ActualWidth"/>
<Binding RelativeSource="{RelativeSource AncestorType=Window, Mode=FindAncestor}" Path="."/>
</MultiBinding>
</Button.Style>
<StackPanel>
<Image Tag="Multi.png" />
<TextBlock Text="Button Text" />
</StackPanel>
</Button>
我添加了后备值,因为否则,我无法从设计视图中看到这两种样式
class ImageButtonStyleSelectorConverter : IMultiValueConverter
{
#region IMultiValueConverter Members
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
Double actualWidth = values[0] as Double? ?? 0;
FrameworkElement element = values[1] as FrameworkElement;
if (element != null)
{
// perform calculations and return button size (using even/odd for illustration purposes)
if (element.Width % 2 == 0)
{
return element.Resources["MultiResButton_Small"];
}
else
{
return element.Resources["MultiResButton_Big"];
}
}
return Binding.DoNothing;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
<Button>
<Button.Style>
<MultiBinding Converter="{StaticResource ImageButtonStyleSelectorConverter}"
FallbackValue="{StaticResource MultiResButton_Big}">
<Binding RelativeSource="{RelativeSource AncestorType=Window, Mode=FindAncestor}" Path="ActualWidth"/>
<Binding RelativeSource="{RelativeSource AncestorType=Window, Mode=FindAncestor}" Path="."/>
</MultiBinding>
</Button.Style>
<StackPanel>
<Image Tag="Multi.png" />
<TextBlock Text="Button Text" />
</StackPanel>
</Button>