Я разрабатывал веб-сайты больше десятилетия теперь, но быстро нашел, что многие мои привычки в разработке для сети бесполезны при разработке для почтовых клиентов. Это вызвало меня огромная сумма разочарования, таким образом, я думал, что задам вопрос, который, надо надеяться, появился бы лучшие практики и необходимые соображения для других как я, кто может разработать для Gmail, перспективы, и т.д. время от времени.
Пример: <style>...</style>
по сравнению со встроенным CSS.
Короче говоря: какие передачи от веб-мира до почтового мира, и что не делает.
Встроенные CSS и таблицы - подумайте о веб-разработке около 2000 года, и все будет в порядке. Монитор кампании - отличный источник информации о том, с чем могут иметь дело почтовые клиенты. Также используйте http://www.emailonacid.com/ для тестирования - избавляет от необходимости отправлять множество тестов.
Управляемый процессор СХД можно записать с помощью класса Regex. проверка электронной почты в соответствии с RFC - сложная вещь. Мы просто запрашиваем AD на предмет существования пользователя.
-121--4817622-Вот что я сделал, чтобы использовать это с образцом MVVM:
У меня есть два набора данных для привязки в моей модели просмотра: один для фактических данных сетки и один для заголовков столбцов. В настоящее время они представлены как два свойства:
// INotifyPropertyChanged support not shown for brevity
public DataTable GridData { get; set; }
public BindingList<ImportColumnInfo> ColumnData { get; set; }
Хитрость в работе с двумя различными наборами данных находится в сетке. Я подклассировал DataGrid и дал сетке дополнительный источник данных ColumnSource в качестве свойства зависимости. Это то, что связано с ColumnData в моей модели представления. Затем я устанавливаю заголовок каждого автоматически генерируемого столбца для соответствующих индексированных данных в источнике данных ColumnSource. Код выглядит следующим образом:
public class ImporterDataGrid : DataGrid
{
protected override void OnAutoGeneratingColumn(DataGridAutoGeneratingColumnEventArgs e)
{
base.OnAutoGeneratingColumn(e);
int columnIndex = this.Columns.Count;
var column = new ImporterDataGridColumn();
column.Header = ColumnSource[columnIndex];
column.Binding = new Binding(e.PropertyName) { Mode = BindingMode.OneWay };
e.Column = column;
}
public IList ColumnSource
{
get { return (IList)GetValue(ColumnSourceProperty); }
set { SetValue(ColumnSourceProperty, value); }
}
public static readonly DependencyProperty ColumnSourceProperty = DependencyProperty.Register("ColumnSource", typeof(IList), typeof(ImporterDataGrid), new FrameworkPropertyMetadata(null));
}
Теперь я могу выполнить обычную привязку данных в шаблонном заголовке моих столбцов, которая будет привязана к данным в свойстве ColumnData моей модели представления.
ОБНОВЛЕНИЕ: Меня попросили показать XAML для моей сетки. Это действительно базовый, но вот он:
<Controls:ImporterDataGrid
AutoGenerateColumns="True" x:Name="previewDataGrid"
VerticalScrollBarVisibility="Visible"
HorizontalScrollBarVisibility="Visible"
IsReadOnly="True"
SelectionMode="Extended"
HeadersVisibility="Column"
ItemsSource="{Binding PreviewData}"
ColumnSource="{Binding PreviewColumnData}"
Style="{StaticResource ImporterDataGridStyle}"
Background="White" CanUserReorderColumns="False" CanUserResizeRows="False"
CanUserSortColumns="False" AlternatingRowBackground="#FFFAFAFA" AllowDrop="True" />
И вот ImporterColumnHeaseStyle:
<Style x:Key="ImporterDataGridColumnHeaderStyle" TargetType="{x:Type toolkit:DataGridColumnHeader}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type toolkit:DataGridColumnHeader}">
<Grid>
<toolkit:DataGridHeaderBorder Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" IsClickable="{TemplateBinding CanUserSort}" IsHovered="False" IsPressed="False" SortDirection="{TemplateBinding SortDirection}">
<Grid>
<CheckBox Height="16" Margin="6,6,16,0" Name="importCheckBox" IsChecked="{Binding Path=Import}" VerticalAlignment="Top">Import Column</CheckBox>
<StackPanel IsEnabled="{Binding Path=Import}">
<ComboBox Height="24" Margin="6,29,6,0" Name="columnTypeComboBox" VerticalAlignment="Top" SelectedValue="{Binding ColumnType}" ItemsSource="{Binding Source={local:EnumList {x:Type Models:ImportColumnType}}}">
</ComboBox>
<TextBox Height="23" Margin="6,6,6,33" Name="customHeadingTextBox" VerticalAlignment="Bottom" Text="{Binding Path=CustomColumnName}" IsEnabled="{Binding ColumnType, Converter={StaticResource ColumnTypeToBooleanConverter}}" />
</StackPanel>
<TextBlock Height="20" Margin="6,0,6,7" Name="originalHeadingTextBlock" Text="{Binding Path=OriginalColumnName}" VerticalAlignment="Bottom" Foreground="Gray" />
</Grid>
</toolkit:DataGridHeaderBorder>
<Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left">
<Thumb.Style>
<Style TargetType="{x:Type Thumb}">
<Setter Property="Width" Value="8"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Cursor" Value="SizeWE"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Thumb.Style>
</Thumb>
<Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right">
<Thumb.Style>
<Style TargetType="{x:Type Thumb}">
<Setter Property="Width" Value="8"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Cursor" Value="SizeWE"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Thumb.Style>
</Thumb>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
-121--3690485- Я делаю это (в довольно короткие времена) для своей работы уже некоторое время. Существует много подводных камней с HTML-письмами. Разные клиенты электронной почты отображают HTML по-разному и делают IE6 продвинутыми.
Вот лето того, что я узнал до сих пор.
Это далеко не полный список, но должен поставить большинство людей на правильный трек.
Я сам тоже нашел это руководство очень полезным: Руководство по поддержке CSS в почтовых клиентах .
Это тоже хорошо, поэтому посмотрите, какой встроенный CSS поддерживается в каком почтовом браузере: http://www.campaignmonitor.com/css/
Я также рекомендую litmusapp (погуглите!). Это хороший инструмент для проверки.