Datagrid templatecolumn更新源触发器显式仅更新第一行

时间:2015-09-23 09:50:41

标签: c# wpf xaml datagrid explicit

我的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>

我的学生管理课程:

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

临时列表(我实际上只是在测试)

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 FindChild

我几乎和这个家伙有同样的问题,但没有人回答他的问题:dude with le same issue

然后我只需通过一个按钮刷新它们:

AccessGrid.ItemsSource = null;
AccessGrid.ItemsSource = StudentManagements;

现在,它工作了一点,我的updatesourcetrigger属性设置为显式,所以我可以保存更改一旦我单击按钮,但只有第一行得到更新,有没有其他方法来显式更新sourcetrigger属性?

1 个答案:

答案 0 :(得分:1)

借助一个小方法来查找所有可视后代(=从模板定义实例化的Framework元素)和一些Linq函数来检查后代是具有给定名称的文本框,您可以显式更新Visual中所有行的绑定树。

这是帮手:

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

应该有所帮助,祝你好运