Propiedades de enlace (ancho / clasificación) de DataGrid en TabPage dinámico

He creado un pequeño proyecto de prueba de wpf para demostrar mi pregunta. Este proyecto contiene una sola ventana wpf. Esta ventana contiene solo unTabControl. Las paginas de estoTabControl se crean dinámicamente desde el límiteItemSource.

Mi XAML:

<Window x:Name="window" x:Class="TestWpf.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:TestWpf"
    Title="MainWindow" Height="350" Width="525">
    <TabControl x:Name="tabControl" BorderThickness="0" ItemsSource ="{Binding MediaLists, ElementName=window, NotifyOnSourceUpdated=True}">
        <TabControl.ItemTemplate>
            <DataTemplate DataType="{x:Type vm:MediaList}">
                <TextBlock Padding="2" Text="{Binding MediaTypeName}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </DataTemplate>
        </TabControl.ItemTemplate>
        <TabControl.ContentTemplate>
            <DataTemplate x:Name="contentTemplate" DataType="{x:Type vm:MediaList}">
                <DataGrid x:Name="dgMediaList" ItemsSource="{Binding Medias, BindsDirectlyToSource=True}" DockPanel.Dock="Top" AutoGenerateColumns="False" HorizontalGridLinesBrush="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}" VerticalGridLinesBrush="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}">
                    <DataGrid.Columns>
                        <DataGridTextColumn x:Name="clmAuthor" Header="Author" Binding="{Binding Author}" IsReadOnly="True" CanUserReorder="False" />
                    <DataGridTextColumn x:Name="clmTitle" Header="Title" Binding="{Binding Title}" IsReadOnly="True" CanUserReorder="False" />
                    </DataGrid.Columns>
                </DataGrid>
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>
</Window>

Y el código detrás es así:

public partial class MainWindow : Window
{
    private readonly ObservableCollection<MediaList> m_MediaLists = new ObservableCollection<MediaList>();
    public ObservableCollection<MediaList> MediaLists { get { return m_MediaLists; } } 
    public MainWindow()
    {
        InitializeComponent();
        MediaList cdList = new MediaList("CDs");
        cdList.Medias.Add(new Media("AuthorCdA", "TitleCdA1"));
        cdList.Medias.Add(new Media("AuthorCdA", "TitleCdA2"));
        cdList.Medias.Add(new Media("AuthorCdB", "TitleCdB1"));
        cdList.Medias.Add(new Media("AuthorCdB", "TitleCdB2"));

        MediaList bookList = new MediaList("Books");
        bookList.Medias.Add(new Media("AuthorBookA", "TitleBookA1"));
        bookList.Medias.Add(new Media("AuthorBookA", "TitleBookA2"));
        bookList.Medias.Add(new Media("AuthorBookB", "TitleBookB1"));
        bookList.Medias.Add(new Media("AuthorBookB", "TitleBookB2"));

        m_MediaLists.Add(cdList);
        m_MediaLists.Add(bookList);
    }
}

ConMediaList como este:

public class MediaList : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    private readonly ObservableCollection<Media> m_Medias = new ObservableCollection<Media>(); 
    public string MediaTypeName { get; private set; }
    public ObservableCollection<Media> Medias { get { return m_Medias; }}

    public MediaList(string typeName)
    {
        MediaTypeName = typeName;
    }
}

YMedia Me gusta esto:

public class Media
{
    public string Author { get; private set; }
    public string Title { get; private set; }
    public Media(string author, string title)
    {
        Author = author;
        Title = title;
    }
}

Así que todo esto funciona bien como puedes ver aquí:

Ahora el problema: escomo salvar elDataGriddiseño de cadaTabPage? Cuando cambio entreTabPages, el ancho de columna se mantiene igual para todas las páginas, pero la clasificación siempre se pierde por completo.

Quiero unir los anchos de columna delDataGrid así como elmulti-columna ordenar la configuración modificada por el usuario en miembros de laMediaList ejemplo.

Entonces, para mantener esta pregunta corta, concentrémonos en los anchos de columna. Agregué los miembros a laMediaList clase:

private DataGridLength m_WidthAuthor = DataGridLength.SizeToCells;
private DataGridLength m_WidthTitle = DataGridLength.SizeToCells;
public DataGridLength WidthAuthor
{
    get { return m_WidthAuthor; }
    set
    {
        if (value == m_WidthAuthor) return;
        m_WidthAuthor = value;
        OnPropertyChanged("WidthAuthor");
    }
}
public DataGridLength WidthTitle
{
    get { return m_WidthTitle; }
    set
    {
        if (value == m_WidthTitle) return;
        m_WidthTitle = value;
        OnPropertyChanged("WidthTitle");
    }
}

e intenté establecer el enlace en el xaml:

<DataGridTextColumn x:Name="clmAuthor" ... Width="{Binding WidthAuthor, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" />
<DataGridTextColumn x:Name="clmTitle" ... Width="{Binding WidthTitle, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" />

Pero desafortunadamente, esto no funciona. He leído en varios artículos sobre SO que un enlace bidireccional sería difícil. Pero incluso el enlace unidireccional no funcionará para mí. (Soy bastante nuevo en wpf / mvvm, así que tal vez use algunas palabras incorrectas aquí ...)

En la ventana de salida del depurador puedo ver estos mensajes de error para mis enlaces de ancho:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=WidthAuthor; DataItem=null; target element is 'DataGridTextColumn' (HashCode=54916642); target property is 'Width' (type 'DataGridLength')
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=WidthTitle; DataItem=null; target element is 'DataGridTextColumn' (HashCode=40809782); target property is 'Width' (type 'DataGridLength')

Entonces, si alguien puede decirme cómo salvarlosDataGrid propiedades para cadaTabPage Yo seria muy feliz. El foco de esta pregunta está en los anchos. La clasificación puede estar sujeta a una nueva pregunta (tenga en cuenta que vincular elSortDirection de las columnas probablemente no funcionará para la clasificación de varias columnas)

EDITAR: he añadidodiag:PresentationTraceSources.TraceLevel=High alBinding expresión a una de las columnasWidth y encontré estos mensajes en la salida de depuración:

System.Windows.Data Warning: 62 : BindingExpression (hash=18270086): Attach to System.Windows.Controls.DataGridTextColumn.Width (hash=37671782)
System.Windows.Data Warning: 64 : BindingExpression (hash=18270086): Use Framework mentor <null>
System.Windows.Data Warning: 67 : BindingExpression (hash=18270086): Resolving source 
System.Windows.Data Warning: 69 : BindingExpression (hash=18270086): Framework mentor not found
System.Windows.Data Warning: 65 : BindingExpression (hash=18270086): Resolve source deferred

Soy demasiado nuevo para wpf para entender qué es esoFramework mentor es y si esto realmente debería sernull.

Respuestas a la pregunta(1)

Su respuesta a la pregunta