Как использовать свойство Attached в стиле? - PullRequest
30 голосов
/ 21 августа 2011

Я создал изображение в ButtonStyle. Теперь я создал Attached Property, чтобы я мог установить источник для этого изображения. Должно быть прямо, но я застрял с этим.

Это мой сокращенный ButtonStyle:

<Style x:Key="ToolBarButtonStyle"
        TargetType="Button">
    ...
    <Image x:Name="toolbarImage"
            Source="{TemplateBinding PrismExt:ImageSourceAttachable:ImageSource}"
            Width="48"
            Height="48" />
    ...
</Style>

И это определение прикрепленного свойства. Обратите внимание, что я понятия не имею, как исправить обратный вызов, так как свойство dependency кажется кнопкой вместо изображения. И Баттон не выставляет мое изображение в своем стиле. Это сложно.

namespace SalesContactManagement.Infrastructure.PrismExt
{
    public class ImgSourceAttachable
    {
        public static void SetImgSource(DependencyObject obj, string imgSource)
        {
            obj.SetValue(ImgSourceProperty, imgSource);
        }

        public static string GetImgSource(DependencyObject obj)
        {
            return obj.GetValue(ImgSourceProperty).ToString();
        }

        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ImgSourceProperty =
            DependencyProperty.RegisterAttached("ImgSource", typeof(string), typeof(ImgSourceAttachable), new PropertyMetadata(Callback));

        private static void Callback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            //((Button)d).Source = new BitmapImage(new Uri(Application.Current.Host.Source, e.NewValue.ToString()));
        }
    }
}

Вот как я устанавливаю источник изображения в XAML:

<Button PrismExt:ImgSourceAttachable.ImgSource="./Images/New.png"
        Style="{StaticResource ToolBarButtonStyle}" />

Есть идеи, пожалуйста? Большое спасибо,

1 Ответ

41 голосов
/ 21 августа 2011

Вот как вы можете установить прикрепленное свойство в стиле

<Style x:Key="ToolBarButtonStyle" TargetType="Button">
    <Setter Property="PrismExt:ImgSourceAttachable.ImgSource"
            Value="./Images/New.png"/>
    <!--...-->
</Style>

При связывании с прикрепленными свойствами, путь должен быть в скобках, поэтому попробуйте использовать RelativeSource Связывание с TemplatedParent вместо

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="Button">
            <Image x:Name="toolbarImage"
                    Source="{Binding RelativeSource={RelativeSource TemplatedParent},
                                    Path=(PrismExt:ImgSourceAttachable.ImgSource)}"
                    Width="48"
                    Height="48">
            </Image>
        </ControlTemplate>
    </Setter.Value>
</Setter>

Редактировать: Приведенный выше код работает в WPF, в Silverlight Image отображается во время выполнения, но в конструкторе происходит сбой за исключением. Вы можете использовать следующий код в PropertyChangedCallback, чтобы получить Image в качестве обходного пути

private static void Callback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    Button button = d as Button;
    Image image = GetVisualChild<Image>(button);
    if (image == null)
    {
        RoutedEventHandler loadedEventHandler = null;
        loadedEventHandler = (object sender, RoutedEventArgs ea) =>
        {
            button.Loaded -= loadedEventHandler;
            button.ApplyTemplate();
            image = GetVisualChild<Image>(button);
            // Here you can use the image
        };
        button.Loaded += loadedEventHandler;
    }
    else
    {
        // Here you can use the image
    }
}
private static T GetVisualChild<T>(DependencyObject parent) where T : DependencyObject
{
    T child = default(T);

    int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
    for (int i = 0; i < numVisuals; i++)
    {
        DependencyObject v = (DependencyObject)VisualTreeHelper.GetChild(parent, i);
        child = v as T;
        if (child == null)
        {
            child = GetVisualChild<T>(v);
        }
        if (child != null)
        {
            break;
        }
    }
    return child;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...