2015-06-11 22 views
4

我有一個DataGrid包含設置對象的信息。目前DataGrid和設置對象之間存在雙向綁定。不過,如果用戶單擊「保存」按鈕,我想在其中放置一個「保存」按鈕,該按鈕僅將DataGrid中所做的更改綁定到對象。但是,我不知道如何調用UpdateSource()爲我的DataGrid的特殊情況。如何調用UpdateSource()以在DataGrid上進行顯式綁定?

這裏是我的xaml.cs代碼:

public void LoadDataFields(Data d) 
     { 
      Grid1.ItemsSource = d.Fields; 
     } 

private void SaveChanges(object sender, RoutedEventArgs e) 
     { 
      BindingExpression be = Grid1.GetBindingExpression(DataGrid.ItemsSourceProperty); 
      be.UpdateSource(); 
     } 

這裏是我的XAML代碼:

<DataGrid x:Name="Grid1" 
        IsReadOnly="False" 
        Height="360" 
        Margin="20,15,20,15" 
        VerticalAlignment="Top" 
        AutoGenerateColumns="False" 
        CanUserAddRows="False" SelectionUnit="Cell" 
        ItemsSource="{Binding data}" 
        > 

      <DataGrid.Columns> 
       <DataGridTemplateColumn Header="Field"> 
        <DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <TextBox Text="{Binding Path=name, Mode=TwoWay, UpdateSourceTrigger=Explicit}"/> 
         </DataTemplate> 
        </DataGridTemplateColumn.CellTemplate> 
       </DataGridTemplateColumn> 
       <DataGridTemplateColumn Header="Length of Field"> 
        <DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <TextBox Text="{Binding Path=length, Mode=TwoWay, UpdateSourceTrigger=Explicit}"/> 
         </DataTemplate> 
        </DataGridTemplateColumn.CellTemplate> 
       </DataGridTemplateColumn> 
      </DataGrid.Columns> 
     </DataGrid> 

有一種簡單的方法來調用UpdateSource(),所以,如果綁定僅發生保存按鈕被點擊?我的猜測是,我只是把GetBindingExpression方法放在了錯誤的屬性中。

回答

4

是的,有一種方法,但它不是一個非常簡單的方法。首先你需要2個輔助方法:

public static T GetVisualChild<T>(Visual parent) where T : Visual 
{ 
    Visual visual; 
    T child = default(T); 

    int childrenCount = VisualTreeHelper.GetChildrenCount(parent); 
    for (int i = 0; i < childrenCount; i++) 
    { 
     visual = (Visual)VisualTreeHelper.GetChild(parent, i); 
     child = visual as T; 
     if (child == null) 
     { 
      child = GetVisualChild<T>(visual); 
     } 
     if (child != null) 
     { 
      break; 
     } 
    } 
    return child; 
} 

public T FindVisualChild<T>(DependencyObject obj, string name) where T : DependencyObject 
{ 
    DependencyObject child; 
    FrameworkElement frameworkElement; 
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) 
    { 
     child = VisualTreeHelper.GetChild(obj, i); 
     frameworkElement = child as FrameworkElement; 
     if (child != null && child is T && frameworkElement != null && frameworkElement.Name == name) 
     { 
      return (T)child; 
     } 
     else 
     { 
      T childOfChild = FindVisualChild<T>(child, name); 
      if (childOfChild != null) 
      { 
       return childOfChild; 
      } 
     } 
    } 

    return null; 
} 

然後你必須給你的綁定控件命名。例如, 「textBox中」:

<DataGridTemplateColumn Header="Field"> 
    <DataGridTemplateColumn.CellTemplate> 
     <DataTemplate> 
      <TextBox x:Name="textBox" Text="{Binding Path=name, Mode=TwoWay, UpdateSourceTrigger=Explicit}"/> 
     </DataTemplate> 
    </DataGridTemplateColumn.CellTemplate> 
</DataGridTemplateColumn> 
<DataGridTemplateColumn Header="Length of Field"> 
    <DataGridTemplateColumn.CellTemplate> 
     <DataTemplate> 
      <TextBox x:Name="textBox" Text="{Binding Path=length, Mode=TwoWay, UpdateSourceTrigger=Explicit}"/> 
     </DataTemplate> 
    </DataGridTemplateColumn.CellTemplate> 
</DataGridTemplateColumn> 

然後在您的SaveChanges方法,您可以使用此代碼:

private void SaveChanges(object sender, RoutedEventArgs e) 
{ 
    DataGridRow dataGridRow; 
    DataGridCellsPresenter dataGridCellsPresenter; 
    DataGridCell dataGridCell; 
    TextBox textBox; 
    BindingExpression bindingExpression; 

    for (int i = 0; i < Grid1.Items.Count; i++) 
    { 
     dataGridRow = (DataGridRow)Grid1.ItemContainerGenerator.ContainerFromIndex(i); 
     dataGridCellsPresenter = GetVisualChild<DataGridCellsPresenter>(dataGridRow); 
     for (int j = 0; j < Grid1.Columns.Count; j++) 
     { 
      dataGridCell = (DataGridCell)dataGridCellsPresenter.ItemContainerGenerator.ContainerFromIndex(j); 
      textBox = FindVisualChild<TextBox>(dataGridCell, "textBox"); 
      if (textBox != null) 
      { 
       bindingExpression = BindingOperations.GetBindingExpression(textBox, TextBox.TextProperty); 
       bindingExpression.UpdateSource(); 
      } 
     } 
    } 
} 

我希望它可以幫助你。

1

您可以嘗試命名您的文本框理解過程使用的語法如下:

BindingExpression be = tbName.GetBindingExpression(TextBox.TextProperty); 
be.UpdateSource(); 

BindingExpression be2 = tbLength.GetBindingExpression(TextBox.TextProperty); 
be2.UpdateSource(); 

,但我會綁定到一個次要集合或對象的副本,如果我不希望更改立即應用,並保存根據用戶請求更新主列表。當有界列表再次被修改時,項目會被更改,刪除或添加,您可以清除次要列表並進行全新複製。或者..如果用戶想要恢復更改,請清除有界的項目並從後面複製項目。

+0

使用TextBox.TextProperty不適用於此,我已經嘗試過。我正在考慮做二次收集,這可能也會起作用。 – reubonwry

相關問題