如何使用Expression Blend编辑在Visual Studio中创建的DataTemplate?

时间:2009-05-05 11:54:10

标签: c# wpf expression-blend

对于那些在实际项目中使用Expression Blend 以及Visual Studio的人,请帮助我理解如何在日常开发/设计任务中使用Blend和Visual Studio ,这是一个真实的场景:

我在Visual Studio中创建了以下简单的WPF应用程序。 显示带有DataTemplate 的客户对象列表,以简单的橙色框显示客户。

我现在希望通过使用Expression Blend将一些pizazz放入此DataTemplate

在Expression Blend中打开项目,以为我会看到橙色框,我可以改变它的颜色,创建动画,因为我将鼠标放在它们上面,调整大小等等。但是,我在Expression Blend中看到的只是一个完全空白的框

所以我理解:

  • Expression Blend 似乎无法理解我的数据来自ViewModel ,因此无法显示。这是Blend的限制还是我需要以某种方式更改我的代码,以便Blend可以解释在运行时会出现什么数据?
  • 我正在使用具有“样本数据”功能的Expression Blend 3。 使用此示例数据功能的最佳方式是什么,这样即使它无法解释C#并了解ViewModel属性中将填充Listbox的数据,我该怎么办?它至少产生一些虚拟数据,以便我可以操纵DataTemplate?

XAML:

<Window x:Class="TestStringFormat234.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <DataTemplate x:Key="DataTemplateCustomers">
            <Border CornerRadius="5" Background="Orange" Padding="5" Margin="3">
                <StackPanel Orientation="Horizontal">
                    <TextBlock>
                    <TextBlock.Text>
                        <MultiBinding StringFormat="{}{0} {1} (hired on {2:MMM dd, yyyy})">
                            <Binding Path="FirstName"/>
                            <Binding Path="LastName"/>
                            <Binding Path="HireDate"/>
                        </MultiBinding>
                    </TextBlock.Text>
                    </TextBlock>
                </StackPanel>
            </Border>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <ListBox ItemsSource="{Binding GetAllCustomers}"
                 ItemTemplate="{StaticResource DataTemplateCustomers}">
        </ListBox>
    </Grid>
</Window>

代码背后:

using System.Windows;
using System.Collections.ObjectModel;
using System;

namespace TestStringFormat234
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            DataContext = new CustomerViewModel();
        }
    }

    //view model
    public class CustomerViewModel
    {
        public ObservableCollection<Customer> GetAllCustomers {
            get {
                ObservableCollection<Customer> customers = new ObservableCollection<Customer>();
                customers.Add(new Customer { FirstName = "Jim", LastName = "Smith", HireDate = DateTime.Parse("2007-12-31") });
                customers.Add(new Customer { FirstName = "Jack", LastName = "Jones", HireDate = DateTime.Parse("2005-12-31") });
                return customers;
            }
        }
    }

    //model
    public class Customer
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime HireDate { get; set; }
    }
}

3 个答案:

答案 0 :(得分:7)

我只是想出来,所以请允许我回答我自己的问题。

我看了Laurent's Bugnion enlighting article on this,事实证明我只需要调整上面的代码,这样我就可以在Expression Blend GUI中看到我的ViewModel中的数据,并且能够在Blend中编辑DataTemplate,保存它,然后在Visual Studio中继续编辑。

基本上更改是:(1)从后面的代码中取出DataContext语句,(2)在XAML中添加“本地”命名空间,(3)在XAML中定义本地数据提供者(“TheDataProvider”),(4) )直接从ListBox绑定它。

以下是完全适用于Expression Blend和Visual Studio的代码:

<强> XAML:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestStringFormat234"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" x:Name="window" x:Class="TestStringFormat234.Window1"
    Title="Window1" Height="300" Width="300" mc:Ignorable="d">
    <Window.Resources>
        <local:CustomerViewModel x:Key="TheDataProvider"/>

        <DataTemplate x:Key="DataTemplateCustomers">
            <Border CornerRadius="5" Padding="5" Margin="3">
                <Border.Background>
                    <LinearGradientBrush EndPoint="1.007,0.463" StartPoint="-0.011,0.519">
                        <GradientStop Color="#FFF4EEEE" Offset="0"/>
                        <GradientStop Color="#FFA1B0E2" Offset="1"/>
                    </LinearGradientBrush>
                </Border.Background>
                <StackPanel Orientation="Horizontal">
                    <TextBlock>
                    <TextBlock.Text>
                        <MultiBinding StringFormat="{}{0} {1} (hired on {2:MMM dd, yyyy})">
                            <Binding Path="FirstName"/>
                            <Binding Path="LastName"/>
                            <Binding Path="HireDate"/>
                        </MultiBinding>
                    </TextBlock.Text>
                    </TextBlock>
                </StackPanel>
            </Border>
        </DataTemplate>
    </Window.Resources>
    <Grid >
        <ListBox 
            ItemsSource="{Binding Path=GetAllCustomers, Source={StaticResource TheDataProvider}}"
            ItemTemplate="{StaticResource DataTemplateCustomers}" />
    </Grid>
</Window>

代码背后:

using System.Windows;
using System.Collections.ObjectModel;
using System;

namespace TestStringFormat234
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }
    }

    //view model
    public class CustomerViewModel
    {
        public ObservableCollection<Customer> GetAllCustomers {
            get {
                ObservableCollection<Customer> customers = new ObservableCollection<Customer>();
                customers.Add(new Customer { FirstName = "Jim", LastName = "Smith", HireDate = DateTime.Parse("2007-12-31") });
                customers.Add(new Customer { FirstName = "Jack", LastName = "Jones", HireDate = DateTime.Parse("2005-12-31") });
                return customers;
            }
        }
    }

    //model
    public class Customer
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime HireDate { get; set; }
    }
}

答案 1 :(得分:2)

我有关于此问题的博文:http://www.robfe.com/2009/08/design-time-data-in-expression-blend-3/

我的帖子是关于在没有的情况下在混合中显示数据,必须在运行时显示或甚至创建数据。

答案 2 :(得分:0)

如果想让Blend和Visual Studio看到datacontext在设计模式下的含义,可以使用页面上的调试选项进行定义。例如,我的页面(在代码隐藏中)将其数据上下文绑定到我的nampespace WP8TestBed中的MainVM,通过将主页面属性的信息通知为d:DataContext,它仅在设计时使用(我可以使用它绑定到它)向导)并且在运行时期间也不会创建视图模型的新实例。

以下是示例,需要所有这些命名空间(d,mc和我的ViewModel(MainVM)所在的本地):

<phone:PhoneApplicationPage
x:Class="WP8TestBed.MainPage"
...
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:local="clr-namespace:WP8TestBed"
mc:Ignorable="d"
Name="Primary"
d:DataContext="{d:DesignInstance local:MainVM}">