Windows Phone 8 用户控制图像按钮,具有不同状态的不同图像
本文关键字:图像 状态 按钮 Phone 用户 控制 Windows | 更新日期: 2023-09-27 18:33:05
我是Windows Phone 8开发的新手(你可以说是知情的菜鸟寻找答案(,我正在寻找以下问题的帮助:
我有用户控件 - 更具体地说是一个包含图像和文本的按钮。我希望该按钮具有以下属性:
- ContentImageNormal - 这将是启用按钮时显示的图像
- 内容图像已禁用 - 这将是禁用按钮时被取消的图像
我现在拥有的是用户控件添加到我的项目中的文件夹用户控件中,我可以使用它。我已经为它创建了一个样式,并更改了禁用按钮的背景等。
我想知道什么:
- 如何更改代码隐藏和其他所需的内容,以便我可以根据需要在下面使用它?
(我将在我的程序中使用该按钮六次,我想将此用户控件用作它的一种模板 - 准备它,所以我只需为两种状态指定 ImageSources,它将完成其余的工作(
所需用法示例:
<UserControls:MainPageButton ContentText="Log In" ContentImageNormal="/ImagePathOrResourceETC.png" ContentImageDisabled="/ImagePathOrResourceETC.png"/>
XAML 我有:
<UserControl x:Class="ProjectNameSpace.UserControls.MainPageButton">
<Grid x:Name="LayoutRoot">
<Button >
<Button.Content>
<Grid>
...omitted...
<Image x:Name="ContentImageHolder" ... />
<TextBlock x:Name="ContentTextBlock" .../>
</Grid>
</Button.Content>
</Button>
</Grid>
</UserControl>
我目前拥有的 C# 代码隐藏:
...usings omitted...
public partial class MainPageButton : UserControl
{
...constructor and text setting omitted for brevity...
public ImageSource ContentImage
{
get
{
return ContentImageHolder.Source;
}
set
{
ContentImageHolder.Source = value;
}
}
}
}
这是非常微不足道的(嗯,这对我来说是,因为我有大量的片段用于大多数困难的东西(,所以这里是作为一个自定义的用户控制。
首先,使用图像创建用户控件。 耶。
<UserControl x:Class="CustomImageControl.Controls.ThreeWay"
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" >
<Image
x:Name="derpImage" />
</UserControl>
特别难,在那里。
接下来,在代码隐藏中,您必须执行以下操作。 首先,为每种类型的映像创建依赖项属性,表示您拥有的任何状态。 在我的示例中,出于空间原因,我省略了 InactiveImage 和 DerpImage 属性。 您可以看到 ActiveImage 的工作原理。 接下来,为控件的状态创建依赖项属性。 在示例中,我有一个定义此内容的状态枚举,但您可以执行任何操作。 在更改时,我检查新值并根据需要更改图像。 容易。
public partial class ThreeWay : UserControl
{
#region ActiveImage
public static readonly DependencyProperty ActiveImageProperty =
DependencyProperty.Register(
"ActiveImage",
typeof(ImageSource),
typeof(ThreeWay),
new UIPropertyMetadata());
public ImageSource ActiveImage
{
get { return (ImageSource)GetValue(ActiveImageProperty); }
set { SetValue(ActiveImageProperty, value); }
}
#endregion
//InactiveImage and DerpImage snipped to keep this short
#region ImageState
public static readonly DependencyProperty ImageStateProperty =
DependencyProperty.Register(
"ImageState",
typeof(State),
typeof(ThreeWay),
new UIPropertyMetadata(State.Derp, OnImageStatePropertyChanged));
private static void OnImageStatePropertyChanged(
DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as ThreeWay).OnImageStateChanged(
e.OldValue as State, e.NewValue as State);
}
private void OnImageStateChanged(State oldValue, State newValue)
{
switch(newValue)
{
case State.Active:
this.derpImage.Source = ActiveImage;
break;
case State.Inactive:
this.derpImage.Source = InactiveImage;
break;
case State.Derp:
this.derpImage.Source = DerpImage;
break;
}
}
public State ImageState
{
get { return (State)GetValue(ImageStateProperty); }
set { SetValue(ImageStateProperty, value); }
}
#endregion
public ThreeWay()
{
InitializeComponent();
}
public enum State
{
Active,
Inactive,
Derp
}
}
仅此而已。 你会像这样使用它:
<cc:ThreeWay xmlns:cc="clr-namespace:CustomImageControl.Controls"
ActiveImage="active.png"
InactiveImage="inactive.png"
DerpImage="derp.jpg"
ImageState="{Binding State}" />
这假定 DataContext 是一个实例,其属性名为 State
的类型为 ThreeWay.State
。 如果没有,可以使用自定义转换器在任意类型(可为空的布尔值?(之间进行转换。
Jan,
对于你的问题,你只是错过了一件事。
在用户控件中,您必须创建如下所示的依赖项属性:
public static readonly DependencyProperty ContentImageNormalProperty =
DependencyProperty.Register("ContentImageNormal",
typeof(ImageSource ),
typeof(MainPageButton));
那么你的属性应该是这样的:
public string ContentImageNormal{ get { return (ImageSource)this.GetValue(ContentImageNormalProperty); }
set { this.SetValue(ContentImageNormalProperty, value); } }
对要设置的每个属性执行此操作...
请参阅此示例:http://stevenhollidge.blogspot.pt/2012/03/dependency-properties-in-user-control.html
我希望这对你有所帮助。
问候塞尔吉奥·蒙泰罗
似乎您真正要做的是创建自定义控件而不是用户控件。因此,我将创建一个从 Button 继承的自定义控件,并使用按钮视觉状态在两个图像之间切换。下面是它的实现:在 ThemeS/Generic.xaml 中添加此样式
<Style TargetType="ButtonWithImage">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMedium}"/>
<Setter Property="Padding" Value="10,5,10,6"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneButtonBasePressedForegroundBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="enablebleImage">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="disableImage">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="ButtonBackground" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="0" Margin="{StaticResource PhoneTouchTargetOverhang}">
<Grid>
<Image x:Name="disableImage" Source="{TemplateBinding EnableImageSource}" Visibility="Collapsed"/>
<Image x:Name="enablebleImage" Source="{TemplateBinding DisableImageSource}"/>
<ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
并定义以下类:
public class ButtonWithImage :Button
{
public static readonly DependencyProperty DisableImageSourceProperty =
DependencyProperty.Register("DisableImageSource", typeof (ImageSource), typeof (ButtonWithImage), new PropertyMetadata(default(ImageSource)));
public ImageSource DisableImageSource
{
get { return (ImageSource) GetValue(DisableImageSourceProperty); }
set { SetValue(DisableImageSourceProperty, value); }
}
public static readonly DependencyProperty EnableImageSourceProperty =
DependencyProperty.Register("EnableImageSource", typeof (ImageSource), typeof (ButtonWithImage), new PropertyMetadata(default(ImageSource)));
public ImageSource EnableImageSource
{
get { return (ImageSource) GetValue(EnableImageSourceProperty); }
set { SetValue(EnableImageSourceProperty, value); }
}
public ButtonWithImage()
{
this.DefaultStyleKey = typeof (Button);
}
}
您可以对图像和文本进行简单的绑定。
对于您的示例:
<Button name="buttonTest">
<Button.Content>
<Grid>
...omitted...
<Image x:Name="ContentImageHolder" Source="{Binding ElementName=buttonTest, Path=IsEnabled, Converter ={StaticResource convertButton}}" Grid.Row="0" />
<TextBlock x:Name="ContentTextBlock" Text="My Sample Text" Grid.Row="1" FontSize="{StaticResource PhoneFontSizeNormal}" FontFamily="{StaticResource PhoneFontFamilyNormal}" Foreground="{StaticResource PhoneForegroundBrush}" TextAlignment="Center"/>
</Grid>
然后,您将创建一个转换器,该转换器将接收值 True 或 False(启用或未启用(,然后在每种状态下返回所需的图像。
您的转换器可能是这样的
public class ButtonImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if((bool) value)
return CreateImage("pack://application:,,,/ButtonEnabled.ico"); // url should be correct
else return CreateImage("pack://application:,,,/ButtonDisable.ico");
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
/// <summary>
/// Method to create an image to bind to icons in treeview
/// </summary>
/// <param name="uriToImage">uri to image in folder.</param>
/// <returns>a bitmap image to bind to image source in tree view</returns>
private BitmapImage CreateImage(string uriToImage)
{
if (!string.IsNullOrEmpty(uriToImage))
{
BitmapImage genericBitmap = new BitmapImage();
genericBitmap.BeginInit();
genericBitmap.UriSource = new Uri(uriToImage);
genericBitmap.EndInit();
return genericBitmap;
}
return null;
}
}
对于文本,如果它依赖于任何属性,您也可以执行相同的操作。