0

我创建了一个 UserControl 来实现一个简单ImageButton的如下:

<UserControl x:Class="MyApp.Common.Controls.ImageButton"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         Name="UC">
<Grid>
    <Button Command="{Binding ElementName=UC, Path=Command}" CommandParameter="{Binding ElementName=UC, Path=CommandParameter}">
        <StackPanel Orientation="Horizontal">
            <Image Source="{Binding ElementName=UC, Path=Image}"
                   Width="{Binding ElementName=UC, Path=ImageWidth}"
                   Height="{Binding ElementName=UC, Path=ImageHeight}"/>
            <TextBlock Text="{Binding ElementName=UC, Path=Text}"  />
        </StackPanel>
    </Button>
</Grid>

这是我控制的代码隐藏:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace MyApp.Common.Controls
{
    public partial class ImageButton : UserControl
    {
        public ImageButton()
        {
            InitializeComponent();
        }

        public ImageSource Image
        {
            get { return (ImageSource)GetValue(ImageProperty); }
            set { SetValue(ImageProperty, value); }
        }

        public static readonly DependencyProperty ImageProperty =
            DependencyProperty.Register("Image", typeof(ImageSource), typeof(ImageButton), new UIPropertyMetadata(null));

        public double ImageWidth
        {
            get { return (double)GetValue(ImageWidthProperty); }
            set { SetValue(ImageWidthProperty, value); }
        }

        public static readonly DependencyProperty ImageWidthProperty =
            DependencyProperty.Register("ImageWidth", typeof(double), typeof(ImageButton), new UIPropertyMetadata(16d));


        public double ImageHeight
        {
            get { return (double)GetValue(ImageHeightProperty); }
            set { SetValue(ImageHeightProperty, value); }
        }

        public static readonly DependencyProperty ImageHeightProperty =
            DependencyProperty.Register("ImageHeight", typeof(double), typeof(ImageButton), new UIPropertyMetadata(16d));


        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(ImageButton), new UIPropertyMetadata(""));

        public ICommand Command
        {
            get { return (ICommand)GetValue(CommandProperty); }
            set { SetValue(CommandProperty, value); }
        }

        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.Register("Command", typeof(ICommand), typeof(ImageButton));



        public object CommandParameter
        {
            get { return GetValue(CommandParameterProperty); }
            set { SetValue(CommandParameterProperty, value); }
        }

        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.Register("CommandParameter", typeof(object), typeof(ImageButton));
    }
}

用法很简单:

            <cc:ImageButton Command="{Binding SearchCommand}" 
                Image="/MyApp;component/Images/magnifier.png"       
                ImageWidth="16" ImageHeight="16"        
                        />

当按钮(绑定到我的 ViewModel 中的 DelegateCommand)被禁用时,图像就会消失。否则,一切都按预期工作。可能是什么问题?禁用时如何使图像以灰度显示?

更新:这是这种奇怪行为的图像截屏

4

3 回答 3

1

我复制了您提供的代码,以查看是否可以重现您遇到的问题。不幸的是,当命令被禁用(或它CanExecute正在返回false)时,我使用的图像并没有消失。您能否提供更多ViewModel您认为可能相关的代码?

要回答您问题的第二部分:

禁用时如何使图像以灰度显示?

据我所知,没有简单的方法可以在 WPF 中对图像进行去饱和处理。相反,我会采用@Vova 建议的方法,即降低Opacity图像的属性。您可以修改您提供的 UserControl XAML,如下所示:

<UserControl x:Class="MyApp.Common.Controls.ImageButton"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         Name="UC">
    <Grid>
        <Button Command="{Binding ElementName=UC, Path=Command}" CommandParameter="{Binding ElementName=UC, Path=CommandParameter}">

            <StackPanel Orientation="Horizontal">
                <Image Source="{Binding ElementName=UC, Path=Image}"
                   Width="{Binding ElementName=UC, Path=ImageWidth}"
                   Height="{Binding ElementName=UC, Path=ImageHeight}">
                    <Image.Style>
                        <Style TargetType="{x:Type Image}">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding  Path=IsEnabled, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}} }" Value="false"  >
                                    <Setter Property="Opacity" Value="0.3" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Image.Style>
                </Image>
                <TextBlock Text="{Binding ElementName=UC, Path=Text}"  />
            </StackPanel>
        </Button>
    </Grid>
</UserControl>

在上面的代码中,如果按钮的属性等于 ,我DataTrigger在图像的Style属性中添加了一个来修改图像的不透明度。IsEnabledfalse

希望这可以帮助!

于 2012-04-09T22:00:11.863 回答
0

我会让它自定义控件,在Property =isEnabled value=false. 在图像上,我会添加一个具有一些不透明度的网格,并使用该触发器控制该不透明度或可见性。祝你好运。我认为没有更简单的方法。

于 2012-04-09T20:48:36.427 回答
0

如前所述,WPF 中没有内置的去饱和支持,但您可以轻松地使用着色器效果来实现它。该链接将您带到一个实现,该实现允许您以仅 XAML 的方式使用该效果。

请注意,对于用 HLSL 编写的着色器,需要编译,并且要进行编译,您需要在您的机器上安装 Direct X SDK。承认,对于这样一个小任务来说,这真是一个野兽。

于 2012-04-10T05:52:16.350 回答