开发者

Bogus WPF / XAML errors in Visual Studio 2010

开发者 https://www.devze.com 2023-02-14 07:34 出处:网络
There are errors hanging around, but at runtime everything works. Right now, I\'m getting Cannot locate resource \'img/icons/silk/arrow_refresh.png\'.

There are errors hanging around, but at runtime everything works.

Right now, I'm getting Cannot locate resource 'img/icons/silk/arrow_refresh.png'.

Bogus WPF / XAML errors in Visual Studio 2010

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

0

精彩评论

暂无评论...
验证码 换一张
取 消