Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.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# 数据网格列宽不小于';自动更新_C#_.net_Wpf_Xaml_Datagrid - Fatal编程技术网

C# 数据网格列宽不小于';自动更新

C# 数据网格列宽不小于';自动更新,c#,.net,wpf,xaml,datagrid,C#,.net,Wpf,Xaml,Datagrid,当Change的值更新时,其列不会更新以适应新值。因此列保持得太小,值被剪裁。 有什么想法吗?解决这个问题的一种方法是在样式设置中定义列的宽度属性,并将该设置绑定到要绑定的对象的属性 <DataGridTextColumn Binding="{Binding Name}" Width="*"/> <DataGridTextColumn Binding="{Binding Change}" Width="Auto"/> 它应该更新你的列宽 RaisePropertyCha

Change
的值更新时,其列不会更新以适应新值。因此列保持得太小,值被剪裁。

有什么想法吗?

解决这个问题的一种方法是在样式设置中定义列的宽度属性,并将该设置绑定到要绑定的对象的属性

<DataGridTextColumn Binding="{Binding Name}" Width="*"/>
<DataGridTextColumn Binding="{Binding Change}" Width="Auto"/>
它应该更新你的列宽

RaisePropertyChanged("ColumnWidth");

我的listview也有类似的问题,这是我在stackoverflow上找到的解决方案

在我的例子中,它将这段代码添加到列表视图绑定到的可观察集合的collectionchanged事件处理程序中:

 public int Change
   {
      get { return m_change; }
      set
      {
         if (m_change != value)
         {
            m_change = value;
            ColumnWidth = WidthAlgo(numberOfCharacters);
            RaisePropertyChanged("Change");
            RaisePropertyChanged("ColumnWidth");
         }
      }
   }
它对我很有效,尽管有时用户会注意到列上的“闪烁”。

你试过吗

void listview_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) {
        // this is a listview control
        GridView view = this.View as GridView;
        foreach(GridViewColumn c in view.Columns) {
            if(double.IsNaN(c.Width)) {
                c.Width = c.ActualWidth;
            }
            c.Width = double.NaN;
        }
    }

数据网格会随着数据变长而增大列大小,但当数据长度减少时,它不会自动减小列大小。在您的示例中,您正确地对齐了“Change”列,并将剩余空间用于“Name”列

现在,当“Change”属性变大到足以增加列的宽度时,“Name”列拒绝收缩以适应,因此您必须自己强制刷新

以下步骤可以为您做到这一点(我已经提供了一个示例应用程序进行演示):

1) 在DataGridTextColumn绑定(除*大小的列外的所有列)中,设置NotifyTargetUpdated=True。
2) 在DataGrid上,向TargetUpdate事件添加处理程序。
3) 在TargetUpdate事件处理程序中:
--a)将DataGrid的*大小列的宽度设置为0。
--b)在DataGrid上调用UpdateLayout()方法。
--c)将DataGrid的*大小列的宽度设置回新的DataGridLength(1,DataGridLengthUnitType.Star)

示例XAML:


代码隐藏示例:

使用系统;
使用System.Collections.ObjectModel;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用系统组件模型;
命名空间DataGridTest
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
私有ObservableCollection myObjectList=新ObservableCollection();
公共主窗口()
{
初始化组件();
(this.FindResource(“MyObjectCollection”)作为CollectionViewSource)。Source=this.myObjectList;
this.myObjectList.Add(newmyobject(){First=“Bob”,Last=“Jones”});
this.myObjectList.Add(newmyobject(){First=“Jane”,Last=“Doe”});
}
私有无效按钮\u单击(对象发送者,路由目标e)
{
this.myObjectList[0]。Last=“BillyOBrian”;
}
私有void dg_TargetUpdated(对象发送方、数据传输方)
{
dg.列[0]。宽度=0;
dg.UpdateLayout();
dg.Columns[0]。宽度=新的DataGridLength(1,DataGridLengthUnitType.Star);
}
}
公共类MyObject:INotifyPropertyChanged
{
私有字符串名;
公共字符串优先
{
获取{返回this.firstName;}
设置
{
if(this.firstName!=值)
{
this.firstName=值;
NotifyPropertyChanged(“第一”);
}
}
}
私有字符串lastName;
最后一个公共字符串
{
获取{返回this.lastName;}
设置
{
if(this.lastName!=值)
{
this.lastName=值;
NotifyPropertyChanged(“上一次”);
}
}
}
公共MyObject(){}
#地区——InotifyProperty变更合同--
公共事件属性更改事件处理程序属性更改;
私有void NotifyPropertyChanged(字符串信息)
{
if(PropertyChanged!=null)
{
PropertyChanged(此,新PropertyChangedEventArgs(信息));
}
}
#endregion InotifyProperty变更合同
}
}

如果需要,WPF只会将datagrid的列宽设置为“自动”,即:无法完全显示内容。因此,当内容的宽度缩小时,列不会调整大小,因为内容仍然可以完全看到

我能看到的强制wpf重新计算列宽度的唯一方法是将它们全部强制为0,然后在后面的代码中返回到auto,并抛出一两个updateLayout(),但这不是很好的编程:-/

基本上,在代码隐藏中:

using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.ComponentModel;

namespace DataGridTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private ObservableCollection<MyObject> myObjectList = new ObservableCollection<MyObject>();

        public MainWindow()
        {
            InitializeComponent();
            (this.FindResource("MyObjectCollection") as CollectionViewSource).Source = this.myObjectList;
            this.myObjectList.Add(new MyObject() { First = "Bob", Last = "Jones" });
            this.myObjectList.Add(new MyObject() { First = "Jane", Last = "Doe" });
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            this.myObjectList[0].Last = "BillyOBrian";
        }

        private void dg_TargetUpdated(object sender, DataTransferEventArgs e)
        {
            dg.Columns[0].Width = 0;
            dg.UpdateLayout();
            dg.Columns[0].Width = new DataGridLength(1, DataGridLengthUnitType.Star);
        }
    }

    public class MyObject : INotifyPropertyChanged
    {
        private string firstName;
        public string First
        {
            get { return this.firstName; }
            set
            {
                if (this.firstName != value)
                {
                    this.firstName = value;
                    NotifyPropertyChanged("First");
                }
            }
        }

        private string lastName;
        public string Last
        {
            get { return this.lastName; }
            set
            {
                if (this.lastName != value)
                {
                    this.lastName = value;
                    NotifyPropertyChanged("Last");
                }
            }
        }

        public MyObject() { }

        #region -- INotifyPropertyChanged Contract --

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        #endregion INotifyPropertyChanged Contract
    }
}

你可能需要一个
dg.UpdateLayout()
或两个(在更新和设置回自动之后)

在样式中定义之前,列不会永远扩展。@sajoshi,如何定义?如果你将宽度更改为
auto
以外的任何值,问题就会消失,但如果你需要它,下面斯科特的答案是正确的!我遍历了所有自动列
dataGrid.columns.Where(c=>c.Width.IsAuto)
,并做了Scott所做的事情。但这并不能解决问题,因为计算ColumnWidth很复杂,因为它基于应用的文本样式。查理·布朗,你是个好人。这是关于如何使我的WPF数据网格美观的最后一个细节,我还没有弄清楚!我实现了这一点,当第一次显示列时,它似乎起了作用。虽然,当我单击datagrid时,它会将列设置为非常小的大小,即使其中的数据更长。这对我来说很有效,但是如果我有ScrollViewer.CanContentScroll=“True”(又名虚拟化),程序将崩溃,出现异常
void listview_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) {
        // this is a listview control
        GridView view = this.View as GridView;
        foreach(GridViewColumn c in view.Columns) {
            if(double.IsNaN(c.Width)) {
                c.Width = c.ActualWidth;
            }
            c.Width = double.NaN;
        }
    }
<DataGridTextColumn Binding="{Binding Path= Id}"  Header="ID" IsReadOnly="True" Width="1*" />
<Window x:Class="DataGridTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <CollectionViewSource x:Key="MyObjectCollection" />
    </Window.Resources>
    <DockPanel>
        <Button DockPanel.Dock="Bottom" Content="Click to Make Item 1s Text Longer" Click="Button_Click" />
        <Grid>
            <DataGrid x:Name="dg" ItemsSource="{Binding Source={StaticResource MyObjectCollection}}" AutoGenerateColumns="False" TargetUpdated="dg_TargetUpdated">
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding First}" Width="1*"/>
                    <DataGridTextColumn Binding="{Binding Last, NotifyOnTargetUpdated=True}"  Width="Auto" />
                </DataGrid.Columns>
            </DataGrid>
        </Grid>

    </DockPanel>
</Window>
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.ComponentModel;

namespace DataGridTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private ObservableCollection<MyObject> myObjectList = new ObservableCollection<MyObject>();

        public MainWindow()
        {
            InitializeComponent();
            (this.FindResource("MyObjectCollection") as CollectionViewSource).Source = this.myObjectList;
            this.myObjectList.Add(new MyObject() { First = "Bob", Last = "Jones" });
            this.myObjectList.Add(new MyObject() { First = "Jane", Last = "Doe" });
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            this.myObjectList[0].Last = "BillyOBrian";
        }

        private void dg_TargetUpdated(object sender, DataTransferEventArgs e)
        {
            dg.Columns[0].Width = 0;
            dg.UpdateLayout();
            dg.Columns[0].Width = new DataGridLength(1, DataGridLengthUnitType.Star);
        }
    }

    public class MyObject : INotifyPropertyChanged
    {
        private string firstName;
        public string First
        {
            get { return this.firstName; }
            set
            {
                if (this.firstName != value)
                {
                    this.firstName = value;
                    NotifyPropertyChanged("First");
                }
            }
        }

        private string lastName;
        public string Last
        {
            get { return this.lastName; }
            set
            {
                if (this.lastName != value)
                {
                    this.lastName = value;
                    NotifyPropertyChanged("Last");
                }
            }
        }

        public MyObject() { }

        #region -- INotifyPropertyChanged Contract --

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        #endregion INotifyPropertyChanged Contract
    }
}
foreach (DataGridColumn c in dg.Columns)
    c.Width = 0;

// Update your DG's source here

foreach (DataGridColumn c in dg.Columns)
    c.Width = DataGridLength.Auto;