首页 文章

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

提问于
浏览
8

对于 those of you using Expression Blend 以及实际项目中的Visual Studio,请帮助我理解 how you use Blend and Visual Studio in your everyday development/design tasks ,这是一个真实的场景:

我在Visual Studio中创建了以下简单的WPF应用程序 . 它 shows a list of customer objects with a DataTemplate 用简单的橙色框显示客户 .

我现在 want put some pizazz into this DataTemplate 使用Expression Blend .

我认为我会看到橙色的盒子,我可以改变它的颜色,创建一个动画,因为我鼠标悬停在它们上面,调整大小等等 . 但是, all I see in Expression Blend is a completely blank box .

所以我理解:

  • Expression Blend can't seem to understand that my data is coming from the ViewModel 因此不显示它 . 这是Blend的限制还是我需要以某种方式更改我的代码,以便Blend可以解释在运行时会出现什么数据?

  • 我正在使用具有"sample data"功能的Expression Blend 3 . What is the best way to use this sample data feature 这样即使它无法解释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>

Code Behind:

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 回答

  • 2

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

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

    基本上改变是:(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>
    

    Code Behind:

    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; }
        }
    }
    
  • 0

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

    我的帖子是关于在混合中显示数据而不必在运行时显示或甚至创建数据 .

  • 7

    如果想让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}">
    

相关问题