Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 动态选项卡页上DataGrid的绑定属性(宽度/排序)_C#_Wpf_Xaml_Datagrid_Tabcontrol - Fatal编程技术网

C# 动态选项卡页上DataGrid的绑定属性(宽度/排序)

C# 动态选项卡页上DataGrid的绑定属性(宽度/排序),c#,wpf,xaml,datagrid,tabcontrol,C#,Wpf,Xaml,Datagrid,Tabcontrol,我创建了一个小wpf测试项目来演示我的问题。此项目包含一个wpf窗口。此窗口仅包含一个选项卡控件。此TabControl的页面是从绑定的ItemSource动态创建的 我的XAML: <Window x:Name="window" x:Class="TestWpf.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.micr

我创建了一个小wpf测试项目来演示我的问题。此项目包含一个wpf窗口。此窗口仅包含一个
选项卡控件
。此
TabControl
的页面是从绑定的
ItemSource
动态创建的

我的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>
媒体
如下:

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);
    }
}
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;
    }
}
这一切都很好,正如你在这里看到的:

现在的问题是:如何为每个
TabPage
保存
DataGrid
的布局?
当我在
TabPage
之间切换时,所有页面的列宽保持不变,但排序总是完全丢失

我想绑定
DataGrid
的列宽以及多列排序设置,这些设置由用户在
MediaList
实例的成员中更改

因此,为了简短地回答这个问题,让我们集中讨论列宽。我将成员添加到
MediaList
类中:

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");
    }
}
并尝试在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}" />
因此,如果有人能告诉我如何为每个
TabPage
保存那些
DataGrid
属性,我将非常高兴。这个问题的焦点是宽度。排序可能是一个新问题的主题(请注意,绑定列的
SortDirection
可能不适用于多列排序)

EDIT:我已将
diag:PresentationTraceSources.TraceLevel=High
添加到
Binding
表达式的一列
Width
中,并在调试输出中找到以下消息:

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
System.Windows.Data警告:62:BindingExpression(hash=18270086):附加到System.Windows.Controls.DataGridTextColumn.Width(hash=37671782)
System.Windows.Data警告:64:BindingExpression(哈希=18270086):使用Framework mentor
System.Windows.Data警告:67:BindingExpression(哈希=18270086):正在解析源
System.Windows.Data警告:69:BindingExpression(哈希=18270086):找不到Framework mentor
System.Windows.Data警告:65:BindingExpression(哈希=18270086):解析源已延迟

我对wpf太陌生了,无法理解什么是
框架导师
,如果这真的应该是
null

,我在的帮助下解决了它。不幸的是,我对wpf的了解仍然很低,以至于我无法解释(以及上述文章的作者)幕后发生了什么,以及这是否真的是一个好的解决方案

以下是我所做的:

实现从“Freezable”继承的“BindingProxy”` 问题之一是,
DataContext
没有继承到
DataGridTextColumn
。因此,目的是将其存储在代理中

public class BindingProxy : Freezable
{
    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    public object Data
    {
        get { return GetValue(DATA_PROPERTY); }
        set { SetValue(DATA_PROPERTY, value); }
    }

    // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DATA_PROPERTY =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}
将“BindingProxy”的实例声明为“DataGrid”中的本地资源` 我在xaml中将此本地资源添加到我的
DataGrid

<DataGrid.Resources>
    <vm:BindingProxy x:Key="proxy" Data="{Binding}" />
</DataGrid.Resources>
瞧,它真管用

我将继续研究如何对多列排序执行此操作。如果我找不到解决办法,我会提出一个新问题。如果在接下来的几天里没有人提出解决方案,我会接受我自己的答案

更新:我解决了多列排序问题

public class BindingProxy : Freezable
{
    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    public object Data
    {
        get { return GetValue(DATA_PROPERTY); }
        set { SetValue(DATA_PROPERTY, value); }
    }

    // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DATA_PROPERTY =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}
<DataGrid.Resources>
    <vm:BindingProxy x:Key="proxy" Data="{Binding}" />
</DataGrid.Resources>
Width="{Binding Data.WidthAuthor, Source={StaticResource proxy}....