WPF XAML试图绑定DataGrid列的宽度 [英] WPF XAML Trying to bind the Width of a DataGrid Column
问题描述
我想将列的宽度"绑定到模型中的属性",以便用户调整大小时可以保存它.我想要一个没有代码的解决方案. 这是我到目前为止的内容:
I'd like to bind the Width of my Columns to a Property in my Model so I can save it if the user resize it. I'd like a solution with no code behind. This is what I have so far:
XAML:
<DataGrid x:Name="dgArticles" AutoGenerateColumns="False" ItemsSource="{Binding Specifications.Articles}" RowDetailsVisibilityMode="Visible">
<DataGrid.Columns>
<DataGridTextColumn x:Name="Number" Header="Number" Binding="{Binding Number}" Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.Specifications.Config.NumberColumnWidth}" MinWidth="70" >
型号:
public class Specifications
{
private ConfigurationGrid config
public ConfigurationGrid Config { get { return config; } set { } }
private ObservableCollection<Article> articles;
public ObservableCollection<Article> Articles
{
get { return articles; }
set { }
}
public class ConfigurationGrid : INotifyPropertyChanged
{
private double numberColumnWidth;
public double NumberColumnWidth
{
get { return numberColumnWidth; }
set { numberColumnWidth = value; OnPropertyChanged("numberColumnWidth"); }
}
public ConfigurationGrid() { }
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this,
new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
我设法将RowDetailsTemplate中的子Datagrid列的宽度绑定到另一个列的宽度,如下所示:
I managed to bind the Width of a sub Datagrid Column which is in my RowDetailsTemplate to the Width of another column like so:
<DataGridTextColumn Header="Quantity" CellStyle="{StaticResource QuantityStyle}" Binding="{Binding Quantity, UpdateSourceTrigger=PropertyChanged, StringFormat=\{0:n\}}"
Width="{Binding Source={x:Reference Mesure}, Path=ActualWidth}"/>
这很好用,但是我不知道为什么它不能在我的主DataGrid上工作. 调试后,我注意到它甚至没有达到NumberColumnWidth的Getter. 有谁知道使其工作的方法吗?谢谢
This works fine but I don't know why it's not working on my main DataGrid. After debugging I noticed that it doesn't even reach the Getter of NumberColumnWidth. Does anyone know a way to make it work? Thank you
我尝试了@ mm8提供的解决方案,但是没有用.它仍然没有到达吸气剂.也许我错过了一些东西.现在的代码如下:
I tried the solution provided by @mm8 but it didn't work. It's still not reaching the Getter. Maybe I missed something. Here is what the code looks like right now:
XAML:
<UserControl x:Class="CachView.Views.GridView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:CachView.ViewModels"
xmlns:conv="clr-namespace:CachView.Converters"
xmlns:util="clr-namespace:CachView.Util"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.DataContext>
<local:ArticleViewModel/>
</UserControl.DataContext>
<Grid Margin="10">
<DataGrid x:Name="dgArticles" AutoGenerateColumns="False" ItemsSource="{Binding Specifications.Articles}" RowDetailsVisibilityMode="Visible">
<DataGrid.Resources>
<util:BindingProxy x:Key="proxy" Data="{Binding}"/>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn x:Name="Number" Header="Number" Binding="{Binding Number}" Width="{Binding Data.Specifications.Config.NumberColumnWidth, Source={StaticResource proxy}}"
MinWidth="70">
</DataGridTextColumn>
后面的代码:
public partial class GridView : UserControl
{
public GridView(ArticleViewModel a)
{
InitializeComponent();
this.DataContext = a;
}
}
我的BindingProxy类与示例中的相同:
And my BindingProxy class is the same as in the example:
class BindingProxy : Freezable
{
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}
我的项目是一个UserControl,可以从WinForm应用程序中使用它.这是它的实现方式以及我如何设置DataContext和属性.这是通过我的WinForm应用程序的控制器完成的.
My project is a UserControl that is meant to be used from a WinForm application. Here is how it is implemented and how I set the DataContext and properties. It is done from the Controller of my WinForm application.
class Controller
{
private ArticleViewModel articleViewModel;
private ElementHost elementHost;
private MainWindow winformView;
public ArticleViewModel ArticleViewModel { get { return articleViewModel; } }
public Collection<Article> Articles { get; set; }
public Specifications Specs { get; set; }
public Controleur(MainWindow view) // The view is received from Program.cs
{
this.winformView = view;
Articles = new Collection<Article>();
populateArticles(); // This create hard coded articles for testing purpose
ConfigurationGrid config= new ConfigurationGrid();
config.NumberColumnWidth = 300;
Specs = new Specifications(Articles);
Specs.Config = config;
articleViewModel = new ArticleViewModel(Specs);
GridView gridView = new GridView(articleViewModel); //This is my WPF UserControl
elementHost = new ElementHost();
elementHost.Dock = DockStyle.Fill;
this.winformView.Controls.Add(elementHost);
elementHost.Child = gridView;
}
我的ViewModel:
My ViewModel:
public class ArticleViewModel
{
private Specifications specifications;
public Specifications Specifications { get { return specifications; } set { } }
public ArticleViewModel() { }
public ArticleViewModel(Specifications c)
{
this.specifications = c;
}
}
欢迎任何帮助或建议.
推荐答案
DataGridTextColumn
不是添加到元素树中的可视元素,因此您将无法绑定到RelativeSource
,因为存在没有祖先绑定.
A DataGridTextColumn
is not a visual element that gets added to the element tree so you won't be able to bind to a RelativeSource
since there are no ancestors to bind to.
如果您希望能够将Width
属性绑定到视图模型属性,则可以使用BindingProxy
对象来捕获DataContext
,如以下博客文章中所述.
If you want to be able to bind the Width
property to a view model property you could use a BindingProxy
object that captures the DataContext
as suggested in the following blog post.
[WPF]当不继承DataContext时如何绑定到数据: https://www.thomaslevesque.com/2011/03/21/wpf-how-to-不继承数据上下文时绑定到数据/
这篇关于WPF XAML试图绑定DataGrid列的宽度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!