Datagrid templatecol列更新源触发器显式地只更新第一行
本文关键字:更新 一行 templatecol 触发器 Datagrid | 更新日期: 2023-09-27 18:14:01
My XAML:
<DataGridTemplateColumn Header=" Student ID" Width="Auto">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox x:Name="StudentIdTextBox" Text="{Binding Path=StudentID, UpdateSourceTrigger=Explicit, Mode=TwoWay}" PreviewTextInput="ID_OnPreviewTextInput" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
我StudentManagementClass :
public class StudentManagement:INotifyPropertyChanged
{
private string StudId;
public bool Check { get; set; }
public int ID { get; set; }
public string StudentID
{
get { return StudId; }
set
{
StudId = value;
PropertyChanged(this, new PropertyChangedEventArgs("StudentID"));
}
}
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public string Birthdate { get; set; }
public string MobileNumber { get; set; }
public string Year { get; set; }
public string Section { get; set; }
public string Department { get; set; }
public string Course { get; set; }
public string Semester { get; set; }
public List<string> AccessLevel { get; set; }
public string AccessLevels { get; set; }
public bool SetTime { get; set; }
public string StartDate { get; set; }
public string Expiration { get; set; }
public event PropertyChangedEventHandler PropertyChanged = delegate { };
}
示例代码:
public ObservableCollection<SM> StudentManagements { get; set; }
Temp List(我实际上只是测试出来的东西)
StudentManagements = new ObservableCollection<SM>();
List<string> AccessLevel = new List<string>();
AccessLevel.Add("a");
AccessLevel.Add("b");
AccessLevel.Add("c");
AccessLevel.Add("d");
AccessLevel.Add("e");
StudentManagements.Add(new SM()
{
StudentID = "1111",
AccessLevel = AccessLevel,
AccessLevels = "a,c",
Birthdate = "1/1/1993",
Course = "",
Department = "",
Expiration = "1/1/1993",
FirstName = "",
Gender = "Male",
LastName = "",
MobileNumber = "09497740052",
Section = "",
Semester = "1st",
StartDate = "1/1/1993",
Year = "2nd",
SetTime = true,
ID = 1
});
StudentManagements.Add(new SM()
{
StudentID = "2222",
AccessLevel = AccessLevel,
AccessLevels = "e,d",
Birthdate = "1/1/1992",
Course = "",
Department = "",
Expiration = "1/1/1992",
FirstName = "",
Gender = "Male",
LastName = "",
MobileNumber = "09497740052",
Section = "",
Semester = "1st",
StartDate = "1/1/1994",
Year = "2nd",
SetTime = true,
ID = 1
});
按钮的显式UpdateSource,只更新第一行,而不是所有编辑的行(请注意,我只是测试它,这就是为什么我只尝试在一列):
x = FindChild<TextBox>(AccessGrid, "StudentIdTextBox");
BindingExpression a = x.GetBindingExpression(TextBox.TextProperty);
a.UpdateSource();
我从这个家伙那里得到FindChild
我对这个家伙也有同样的问题,但是没有人回答他的问题:dude with le same issue
然后我通过按钮刷新它们:
AccessGrid.ItemsSource = null;
AccessGrid.ItemsSource = StudentManagements;
现在,它工作了一点,我的updatesourcetrigger属性被设置为显式的,所以我可以保存更改,一旦我点击按钮,但只有第一行得到更新,有任何其他方法来更新sourcetrigger属性显式?
使用一个小方法来查找所有的可视后代(=从模板定义实例化的框架元素)和一些Linq函数来检查后代是否是具有给定名称的文本框,您可以显式地更新可视树中所有行的绑定。
下面是帮助器:
public static class VisualTreeHelperExtension
{
struct StackElement
{
public FrameworkElement Element { get; set; }
public int Position { get; set; }
}
public static IEnumerable<FrameworkElement> FindAllVisualDescendants(this FrameworkElement parent)
{
if (parent == null)
yield break;
Stack<StackElement> stack = new Stack<StackElement>();
int i = 0;
while (true)
{
if (i < VisualTreeHelper.GetChildrenCount(parent))
{
FrameworkElement child = VisualTreeHelper.GetChild(parent, i) as FrameworkElement;
if (child != null)
{
if (child != null)
yield return child;
stack.Push(new StackElement { Element = parent, Position = i });
parent = child;
i = 0;
continue;
}
++i;
}
else
{
// back at the root of the search
if (stack.Count == 0)
yield break;
StackElement element = stack.Pop();
parent = element.Element;
i = element.Position;
++i;
}
}
}
}
在按钮上点击,只需要调用助手:
private void Button_Click(object sender, RoutedEventArgs e)
{
// to check :
MessageBox.Show(StudentManagements[1].StudentID.ToString());
var textboxes = AccessGrid.FindAllVisualDescendants()
.Where(elt => elt.Name == "StudentIdTextBox" )
.OfType<TextBox>();
foreach (var textbox in textboxes)
{
BindingExpression binding = textbox.GetBindingExpression(TextBox.TextProperty);
binding.UpdateSource();
}
// to check :
MessageBox.Show(StudentManagements[1].StudentID.ToString());
}
应该有帮助,祝你好运