开发者

In WPF can I manually "reset" or re-test the triggers for a Style?

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.

开发者_C百科

(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


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


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜