在WPF中我可以手动“重置”或者重新测试样式的触发器?

发布于 2024-11-16 10:33:22 字数 1181 浏览 4 评论 0原文

我想做的是在事件触发时“重新测试”触发器。这是因为 Trigger 绑定到 DataRowViewRow.RowState 属性,该属性不会触发 PropertyChanged > 通知要求 for 触发器重新评估其条件。

(请参阅本页底部的帖子:WpfToolkit DataGrid:突出显示修改的行< /a>)

我可以在每个控件的基础上在事件中重新设置触发器,如下所示:

    private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        Style s = ((TextBox)sender).Style;
        ((TextBox)sender).Style = null;
        ((TextBox)sender).Style = s;
    }

但是我有一个DataGrid 具有许多控件,并且全部使用四种 Style 之一。我想做的是用伪代码做类似的事情:

Style1.reTest();
Style2.reTest();
...

有什么办法可以做到这一点吗?第一个问题是您无法命名样式,因此从外部访问 xmlns 是有问题的。第二个问题是 Style 没有提供此功能的方法。

任何帮助最感激。

编辑1:我可以使用资源字典获取样式(不敢相信我没有想到它,我认为它们不会在那里,因为我没有命名它们)。如果你还没有命名它们,你可以像这样抓取它们(显然改变类型):

Style s = (Style)Resources[typeof(System.Windows.Controls.TextBox)];

Edit2:我已经找到了答案,并将在 Stackoverflow 允许时发布它。非常感谢您的所有回复:)

Fugu

What I want to do is 're-test' a Trigger when an event is fired. This is because the Trigger is binding to the Row.RowState property of a DataRowView, which does NOT fire the PropertyChanged notification required the for trigger to re-evaluate its condition.

(see the post at the bottom of this page: WpfToolkit DataGrid: Highlight modified rows)

I can re-set a Trigger on a per-control basis in an event like so:

    private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        Style s = ((TextBox)sender).Style;
        ((TextBox)sender).Style = null;
        ((TextBox)sender).Style = s;
    }

But I have a DataGrid with many controls and which all use one of four Styles. What I would like to do is do something like, in psuedo code:

Style1.reTest();
Style2.reTest();
...

Is there any way to do that? The first problem is that you can't name styles, so accessing them externally to the xmlns is problematic. The second problem is that a Style does not have a method which provides this functionality.

Any help most apppreciated.

EDIT 1: I can get the styles using the resource dictionary (can't believe I hadn't thought of it, I assumed they wouldn't be in there because I hadn't named them). If you haven't named them you can grab them like this (changing the type obviously):

Style s = (Style)Resources[typeof(System.Windows.Controls.TextBox)];

Edit2: I have found the answer and will post it when Stackoverflow allows me to. Many thanks for all the responses :)

Fugu

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

青春如此纠结 2024-11-23 10:33:22

我知道这不是对您的问题的直接答案,但一种可能性是侦听来自 DataTable 的适当更改事件并更新 DataGridRow 上附加的 RowState 属性。然后,您的 DataTrigger 将使用此附加的 RowState 属性。我想说这比派生您自己的自定义 DataRowView 类更好。

另一种选择是向数据表添加额外的列来存储行状态。每当行状态发生变化时,您都会更新该值。在您的 DataGrid 中,您隐藏了这个额外的列,但它现在可用于绑定到 DataTrigger

编辑:详细解释选项 #2

DataTable myTable
myTable.Columns.Add("Foo");
//etc etc
myTable.Columns.Add("INTERNAL_STATUS",typeof(DataRowState));


//Attach event handlers to DataTable.RowChanged, DataTable.ColumnChanged, etc
//I will just show RowChanged here

    private void Row_Changed(object sender, DataRowChangeEventArgs e)
        {
                e.Row["INTERNAL_STATUS"] = e.Row.RowState;
        }

//Now in your XAML you can use the INTERNAL_STATUS in your data trigger

I know this isn't a direct answer to your question, but one possibility would be to listen to the appropriate change events coming from the DataTable and to update an attached RowState property on DataGridRow. Your DataTrigger would then use this attached RowState property. I would say this is preferable to deriving your own custom DataRowView class.

Another option would be to add an extra column to your DataTable to store the row state. Whenever the row state changes you update this value. In your DataGrid you hide this extra column but it is now available for binding to a DataTrigger

Edit: Explaining option #2 in detail

DataTable myTable
myTable.Columns.Add("Foo");
//etc etc
myTable.Columns.Add("INTERNAL_STATUS",typeof(DataRowState));


//Attach event handlers to DataTable.RowChanged, DataTable.ColumnChanged, etc
//I will just show RowChanged here

    private void Row_Changed(object sender, DataRowChangeEventArgs e)
        {
                e.Row["INTERNAL_STATUS"] = e.Row.RowState;
        }

//Now in your XAML you can use the INTERNAL_STATUS in your data trigger
稀香 2024-11-23 10:33:22

设置 TargetName 应该可以工作,但它不能以某种样式工作。如果你仔细想想,这是有道理的:如果你在样式中设置目标名称,运行时应该在什么范围内查找该名称?
因此,您可以尝试设置目标名称,但在元素本身的触发器中,而不是在样式中。

Setting the TargetName should work, however it cannot work in a style. If you think about it, it makes sense: if you set the target name in the style in what scope should the runtime look for the name?
So you could try to set target name but in the triggers of the element itself, not in the style.

淡莣 2024-11-23 10:33:22

做到了!

假设您的 XAML 中有一些没有名称的样式(因为您希望它们应用于特定类型的所有控件)。

执行此操作以重置/重新评估触发器,将 TextBox 交换为适当的类型:

        Style s = (Style)Resources[typeof(System.Windows.Controls.TextBox)];
        Resources[typeof(System.Windows.Controls.TextBox)] = null;
        Resources[typeof(System.Windows.Controls.TextBox)] = s;

也许对触发器而不是整个样式执行相同的操作会更快,我需要正确测试它,因为它需要一个循环来添加触发回到 TriggersCollection (所以它可能不会更快)。

如果您为样式命名,关键是字符串形式的名称,而不是样式适用的类型。

如果您想在 DataGrid 中的行被修改时突出显示,您可以将上面的代码粘贴到事件中。

Did it!

Let's say you have some styles in your XAML which don't have names (because you want them to apply to all controls of a particular type).

Do this to reset/re-evaluate the triggers, swapping TextBox for the appropriate type:

        Style s = (Style)Resources[typeof(System.Windows.Controls.TextBox)];
        Resources[typeof(System.Windows.Controls.TextBox)] = null;
        Resources[typeof(System.Windows.Controls.TextBox)] = s;

Maybe it's quicker to do the same for the triggers instead of the entire Style, I would need to test this properly as it would require a loop to add the triggers back to the TriggersCollection (so it probably isn't quicker).

If you have names your styles, the key is the name as a string rather than the type the Style applies to.

If you want to highlight rows in a DataGrid when they are modified you can stick the code above in an event.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文