如何使用XAML将属性附加到对象

时间:2012-01-01 23:38:53

标签: wpf xaml wpf-controls

我正在尝试格式化我的ListBoxItem模板以包含图像。我可以向ListBoxItem添加一个图像,但我不太清楚如何设置该图像的值。

ListBoxItem的模板:

        <Style TargetType="{x:Type ListBoxItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Border Name="Border" Padding="2" SnapsToDevicePixels="true">
                        <StackPanel Orientation="Horizontal" >
                            <Image Source="{Binding Path=Source}" Height="16" Width="16" HorizontalAlignment="Center" VerticalAlignment="Center" />
                            <ContentPresenter Name="ContentPresenter" HorizontalAlignment="Stretch" Width="Auto" />
                        </StackPanel>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsSelected" Value="true">
                            <Setter TargetName="Border" Property="Background" Value="{StaticResource ListBoxItem_BackgroundBrush_Selected}"/>
                            <Setter TargetName="ContentPresenter" Property="TextElement.FontWeight" Value="Bold"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="{StaticResource TabItem_BackgroundBrush_Disabled}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

ListBox代码示例:

   <ListBox Name="listBox_LibAll" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
       <ListBoxItem Content="Item 1" />
       <ListBoxItem Content="Item 2" />
       <ListBoxItem Content="Item 3" />                                
   </ListBox>

输出: enter image description here

如果您查看图片,您会注意到图像有一个位置,我只是不知道如何设置它的值。我想我可以以某种方式将“Source”属性附加到ListBoxItem

2 个答案:

答案 0 :(得分:2)

您可以对RelativeSource或某些attached property进行Tag绑定。

Source="{Binding Tag, RelativeSource={RelativeSource AncestorType=ListBoxItem}}"

<ListBoxItem Tag="SomePath" />
Source="{Binding (ns:AttachedProperties.Source), RelativeSource={RelativeSource AncestorType=ListBoxItem}}"

<ListBoxItem ns:AttachedProperties.Source="SomePath" />

您还可以使用here所示的动态资源。

然而,最干净的解决方案是使内容复杂化,即使ListBoxItem主机成为UserControl或自定义控件,例如实际上具有正确的属性图片。您通常不应覆盖ListBoxItems的控件模板,而应使用ListBox的ItemTemplatedata template数据。

答案 1 :(得分:0)

你快到了。

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

    public class ImageItem: DependencyObject
    {
        public static readonly DependencyProperty SourceProperty =
            DependencyProperty.RegisterAttached("Source",
            typeof(string),
            typeof(DependencyObject),
            new PropertyMetadata((o, e) => 
            {
                //System.Diagnostics.Debugger.Break();
            }));

        public static string GetSource(DependencyObject o)
        {
            return (string)o.GetValue(ImageItem.SourceProperty);
        }

        public static void SetSource(DependencyObject o, string e)
        {
            o.SetValue(ImageItem.SourceProperty, e);
        }
    }
}

标记:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.Resources>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListBoxItem">
                            <Border Name="Border" Padding="2" SnapsToDevicePixels="true">
                                <StackPanel Orientation="Horizontal" >
                                    <Image Source="{Binding Path=Source, 
                                           RelativeSource={RelativeSource AncestorType=ListBoxItem}}" 
                                           Height="16" 
                                           Width="16" 
                                           HorizontalAlignment="Center" VerticalAlignment="Center" />
                                    <ContentPresenter Name="ContentPresenter" HorizontalAlignment="Stretch" Width="Auto" />
                                </StackPanel>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsSelected" Value="true">
                                    <Setter TargetName="Border" Property="Background" Value="{StaticResource ListBoxItem_BackgroundBrush_Selected}"/>
                                    <Setter TargetName="ContentPresenter" Property="TextElement.FontWeight" Value="Bold"/>
                                </Trigger>
                                <Trigger Property="IsEnabled" Value="false">
                                    <Setter Property="Foreground" Value="{StaticResource TabItem_BackgroundBrush_Disabled}"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Grid.Resources>
        <ListBox Name="listBox_LibAll" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
            <ListBoxItem local:ImageItem.Source="/WpfApplication1;component/Penguins.jpg" Content="Item 1" />
            <ListBoxItem Content="Item 2" />
            <ListBoxItem Content="Item 3" />
        </ListBox>
    </Grid>
</Window>