2017-03-16 1 views
0

사용자가 크기를 조정하면 저장할 수 있도록 내 열의 너비를 내 모델의 속성에 바인딩하고 싶습니다. 코드가없는 솔루션을 원합니다. 이것은 내가 지금까지 무엇을 가지고 :WPF XAML DataGrid 열의 너비 바인딩 시도

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)); 
    } 
} 

나는에있는 하위에서 Datagrid 열의 너비를 바인딩 관리 제 RowDetailsTemplate을 다음과 같이 다른 열의 너비로 설정합니다.

<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에 도달하지 못하는 것으로 나타났습니다. 누구나 작동하도록하는 방법을 알고 있습니까? 내가 @ MM8가 제공하는 솔루션을 시도했지만 작동하지 않았다

편집

주셔서 감사합니다. 아직 Getter에 도달하지 못했습니다. 어쩌면 내가 뭔가를 놓친 것 같아.

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 클래스의 예에서와 동일합니다

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)); 
} 
다음 코드는 지금 모습입니다

내 프로젝트는 WinForm 응용 프로그램에서 사용하기위한 UserControl입니다. 다음은 구현 방법과 DataContext 및 속성 설정 방법입니다. 그것은 내 WinForm 응용 프로그램의 컨트롤러에서 수행됩니다.

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

내 뷰 모델은 :

public class ArticleViewModel 
{ 
    private Specifications specifications; 
    public Specifications Specifications { get { return specifications; } set { } } 



    public ArticleViewModel() { } 

    public ArticleViewModel(Specifications c) 
    { 
     this.specifications = c; 
    } 
} 

어떤 도움이나 제안을 환영합니다.

답변

0

DataGridTextColumn은 요소 트리에 추가되는 시각적 요소가 아니므로 RelativeSource에 바인딩 할 조상이 없기 때문에 바인딩 할 수 없습니다.

Width 속성을보기 모델 속성에 바인딩하려면 다음 블로그 게시물에서 제안하는대로 DataContext을 캡처하는 BindingProxy 개체를 사용할 수 있습니다.

[WPF] DataContext를 상속하지 않는 경우 데이터 바인딩 방법 :https://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/

+0

나는이 솔루션을 테스트하지만 작동하지 않습니다. 속성에 바인딩 할 너비를 가져올 수 없습니다. 다시 한번 getter에 도달하지 않습니다. – Hugo

+0

분명히 당신은 잘못된 것을했습니다.BindingProxy의 Data 속성을 뷰 모델에 바인딩하고 누군가가 실수 위치를 지적 할 수 있도록하려면 코드를 게시해야합니다. – mm8

+0

새 코드를 추가하기 위해 내 게시물을 편집했습니다. – Hugo