Bogus WPF / XAML errors in Visual Studio 2010
There are errors hanging around, but at runtime everything works.
Right now, I'm getting Cannot locate resource 'img/icons/silk/arrow_refresh.png'.
I've got a simple UserControl called ImageButton (doesn't everyone?):
<UserControl x:Class="MyProj.src.controls.ImageButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d">
<Button Name="btnButton" Click="btnButton_Click">
<StackPanel Orientation="Horizontal">
<Image Name="btnImage" Stretch="None" />
<TextBlock Name="btnText" />
</StackPanel>
</Button>
</UserControl>
Which does what you'd expect:
[ContentProperty("Text")]
public partial class ImageButton : UserControl
{
public String Image { set { btnImage.Source = GuiUtil.CreateBitmapImage(value); } }
public String Text { set { btnText.Text = value; } }
public double Gap { set { btnImage.Margin = new Thickness(0, 0, value, 0); } }
public bool ToolBarStyle { set { if (value) {
btnButton.Style = (Style)FindResource(ToolBar.ButtonStyleKey); } }
}
public bool IsCancel { set { btnButton.IsCancel = value; } }
public bool IsDefault { set { btnButton.IsDefault = value; } }
public event RoutedEventHandler Click;
public ImageButton()
{
InitializeComponent();
}
private void btnButton_Click(object sender, RoutedEventArgs e)
{
if (Click != null)
{
Click(sender, e);
}
}
}
Where CreateBitmapImage is the following:
public static BitmapImage CreateBitmapImage(string imagePath)
{
BitmapImage icon = new BitmapImage();
icon.BeginInit();
icon.UriSource = new Uri(String.Format("pack://application:,,,/{0}", imagePath));
icon.EndInit();
return icon;
}
I can't see the design view of any xaml file 开发者_高级运维that uses an ImageButton like such:
<Window
foo="bar"
xmlns:wpfControl="clr-namespace:MyProj.src.controls">
<Grid>
<wpfControl:ImageButton ToolBarStyle="True" Gap="3"
Click="btnRefresh_Click" Text="Refresh"
Image="img/icons/silk/arrow_refresh.png" />
</Grid>
</Window>
Why is VS complaining?
I would suggest using Dependency Properties and Bindings when creating a Control. The benefits of this will be many, for example you'll be able to Bind the Image property for the ImageButton
and you won't run in to problems like the one in your question.
Instead of using the setter in the Properties to set the Image source and TextBlock Text, you can bind them to the properties for the ImageButton
UserControl
.
Update
I put together a small sample project with ImageButton
here: http://www.mediafire.com/?vlk4m7svttyjd6t
Your Xaml can look like this
<UserControl ...
x:Name="imageButton">
<Button...>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding ElementName=imageButton, Path=Image}" .../>
<TextBlock Text="{Binding ElementName=imageButton, Path=Text}" .../>
</StackPanel>
</Button>
</UserControl>
And then you replace the CLR Properties with Dependency properties like below in code behind
public partial class ImageButton : UserControl
{
public static readonly DependencyProperty ImageProperty =
DependencyProperty.Register("Image",
typeof(ImageSource),
typeof(ImageButton),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure));
public ImageSource Image
{
get { return (ImageSource)base.GetValue(ImageProperty); }
set { base.SetValue(ImageProperty, value); }
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text",
typeof(string),
typeof(ImageButton),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure));
public string Text
{
get { return (string)base.GetValue(TextProperty); }
set { base.SetValue(TextProperty, value); }
}
//...
}
For the Gap property you can either Bind Margin with a Converter or use the PropertyChangedCallback
to set it in code behind.
Hope that helps
精彩评论