How do I stop "Reason" being changed to "Fixed" when transitioning from "Resolved" to "Closed"
If a work item is transitioned to "Resolved" using a "Reason" other than "Fixed" (for example, "Obsolete") and the assignee agrees with the reason and attempts to Close the work item, the Reason is being modified to "Fixed". I attempted to change this default using the Work Item Process editor, but it says at least one default is required. So, the question is, is it possible to get TFS to keep the selected reason code when transitioning from Resolved to Closed and NOT change it to "Fixed". Users are missing this change and inadvertantly sometimes closing with the wrong reason code.
Answers
Hi Bill2010,
If you use build-in work item control type, The field [System.Reason] can only be selected by manually and the default value is defined in <DefaultReason> element.
To keep the original value for this field, you can use a custom WIT control. Following steps show how to create and use a custom control( please refer to http://msdn.microsoft.com/en-us/library/bb286959.aspx for detail )
1. Create a UserControl class library.
1) Create a class library project (ie CustomWitControl)
2) Add a UserControl to this project(ie CustomWitControl.UseOriginalReason)
3) Add a label "label1" in the design mode().
4) Implement interface IWorkItemControl, you can just use following code.
#region IWorkItemControl Members
private EventHandlerList m_events;
private EventHandlerList Events
{
get
{
if (m_events == null)
{
m_events = new EventHandlerList();
}
return m_events;
}
}
private static object EventBeforeUpdateDatasource = new object();
public event EventHandler BeforeUpdateDatasource
{
add { Events.AddHandler(EventBeforeUpdateDatasource, value); }
remove { Events.RemoveHandler(EventBeforeUpdateDatasource, value); }
}
protected virtual void OnBeforeUpdateDatasource(EventArgs eventArgs)
{
EventHandler handler = (EventHandler)Events[EventBeforeUpdateDatasource];
if (handler != null)
{
handler.Invoke(this, eventArgs);
}
}
private static object EventAfterUpdateDatasource = new object();
public event EventHandler AfterUpdateDatasource
{
add { Events.AddHandler(EventAfterUpdateDatasource, value); }
remove { Events.RemoveHandler(EventAfterUpdateDatasource, value); }
}
void IWorkItemControl.Clear()
{
label1.Text = string.Empty;
}
void IWorkItemControl.FlushToDatasource()
{
// nothing to do
}
void IWorkItemControl.InvalidateDatasource()
{
}
private StringDictionary m_properties;
StringDictionary IWorkItemControl.Properties
{
get
{
return m_properties;
}
set
{
m_properties = value;
}
}
private bool m_readOnly;
bool IWorkItemControl.ReadOnly
{
get
{
return m_readOnly;
}
set
{
m_readOnly = value;
}
}
private IServiceProvider m_serviceProvider;
void IWorkItemControl.SetSite(IServiceProvider serviceProvider)
{
m_serviceProvider = serviceProvider;
}
private WorkItem m_workItem;
object IWorkItemControl.WorkItemDatasource
{
get
{
return m_workItem;
}
set
{
m_workItem = (WorkItem)value;
if (m_workItem != null)
{
m_workItem.FieldChanged += new WorkItemFieldChangeEventHandler(WIChanged);
}
}
}
void WIChanged(object sender, WorkItemEventArgs e)
{
try
{
if (e.Field.Id == (int)CoreField.State && e.Field.OriginalValue.ToString() == "Resolved" && e.Field.Value.ToString() == "Closed")
{
m_workItem.Reason = m_workItem.Fields[CoreField.Reason].OriginalValue.ToString();
}
}
catch { }
}
private string m_fieldName;
string IWorkItemControl.WorkItemFieldName
{
get
{
return m_fieldName;
}
set
{
m_fieldName = value;
}
}
#endregion
5) Compile the project.
2. Make VS2008 use this control
1) Copy CustomWitControl.dll to " C:\ProgramData\Microsoft\Team Foundation\Work Item Tracking\Custom Controls\9.0"(Vista, Server2008 or Win7), If this location does not exist, create it.
2) Create a file named " CustomWitControl.wicc" in the same location, add following code to this file.
<?xml version="1.0"?>
<CustomControl xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Assembly>CustomWitControl.dll</Assembly>
<FullClassName>CustomWitControl.UseOriginalReason</FullClassName>
</CustomControl>
3. Modify the work item type.( It is better to use Power Tools to do this operation. )
1) Create a demo field which is just used to assign to custom control, so that WI Edit UI will set the WorkItemDatasource Property
2) Add controls in Layout Tab. The Field Type of demo field is UseOriginalReason
After step 2, re-open VS2008, you will see "UseOriginalReason" in the dropdown list.
3) Save it.
4. Create a new work item, and now you can keep the original reason.
In additional, it is needed to copy CustomWitControl.dll and CustomWitControl.wicc to each client PC.
If there is anything unclear, please let me known.
Best Regards,
Ruiz
Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread. Sincerely, Ruiz Yi- Marked As Answer byBill2010 Monday, November 09, 2009 6:31 PM
All Replies
Hi Bill2010,
If you use build-in work item control type, The field [System.Reason] can only be selected by manually and the default value is defined in <DefaultReason> element.
To keep the original value for this field, you can use a custom WIT control. Following steps show how to create and use a custom control( please refer to http://msdn.microsoft.com/en-us/library/bb286959.aspx for detail )
1. Create a UserControl class library.
1) Create a class library project (ie CustomWitControl)
2) Add a UserControl to this project(ie CustomWitControl.UseOriginalReason)
3) Add a label "label1" in the design mode().
4) Implement interface IWorkItemControl, you can just use following code.
#region IWorkItemControl Members
private EventHandlerList m_events;
private EventHandlerList Events
{
get
{
if (m_events == null)
{
m_events = new EventHandlerList();
}
return m_events;
}
}
private static object EventBeforeUpdateDatasource = new object();
public event EventHandler BeforeUpdateDatasource
{
add { Events.AddHandler(EventBeforeUpdateDatasource, value); }
remove { Events.RemoveHandler(EventBeforeUpdateDatasource, value); }
}
protected virtual void OnBeforeUpdateDatasource(EventArgs eventArgs)
{
EventHandler handler = (EventHandler)Events[EventBeforeUpdateDatasource];
if (handler != null)
{
handler.Invoke(this, eventArgs);
}
}
private static object EventAfterUpdateDatasource = new object();
public event EventHandler AfterUpdateDatasource
{
add { Events.AddHandler(EventAfterUpdateDatasource, value); }
remove { Events.RemoveHandler(EventAfterUpdateDatasource, value); }
}
void IWorkItemControl.Clear()
{
label1.Text = string.Empty;
}
void IWorkItemControl.FlushToDatasource()
{
// nothing to do
}
void IWorkItemControl.InvalidateDatasource()
{
}
private StringDictionary m_properties;
StringDictionary IWorkItemControl.Properties
{
get
{
return m_properties;
}
set
{
m_properties = value;
}
}
private bool m_readOnly;
bool IWorkItemControl.ReadOnly
{
get
{
return m_readOnly;
}
set
{
m_readOnly = value;
}
}
private IServiceProvider m_serviceProvider;
void IWorkItemControl.SetSite(IServiceProvider serviceProvider)
{
m_serviceProvider = serviceProvider;
}
private WorkItem m_workItem;
object IWorkItemControl.WorkItemDatasource
{
get
{
return m_workItem;
}
set
{
m_workItem = (WorkItem)value;
if (m_workItem != null)
{
m_workItem.FieldChanged += new WorkItemFieldChangeEventHandler(WIChanged);
}
}
}
void WIChanged(object sender, WorkItemEventArgs e)
{
try
{
if (e.Field.Id == (int)CoreField.State && e.Field.OriginalValue.ToString() == "Resolved" && e.Field.Value.ToString() == "Closed")
{
m_workItem.Reason = m_workItem.Fields[CoreField.Reason].OriginalValue.ToString();
}
}
catch { }
}
private string m_fieldName;
string IWorkItemControl.WorkItemFieldName
{
get
{
return m_fieldName;
}
set
{
m_fieldName = value;
}
}
#endregion
5) Compile the project.
2. Make VS2008 use this control
1) Copy CustomWitControl.dll to " C:\ProgramData\Microsoft\Team Foundation\Work Item Tracking\Custom Controls\9.0"(Vista, Server2008 or Win7), If this location does not exist, create it.
2) Create a file named " CustomWitControl.wicc" in the same location, add following code to this file.
<?xml version="1.0"?>
<CustomControl xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Assembly>CustomWitControl.dll</Assembly>
<FullClassName>CustomWitControl.UseOriginalReason</FullClassName>
</CustomControl>
3. Modify the work item type.( It is better to use Power Tools to do this operation. )
1) Create a demo field which is just used to assign to custom control, so that WI Edit UI will set the WorkItemDatasource Property
2) Add controls in Layout Tab. The Field Type of demo field is UseOriginalReason
After step 2, re-open VS2008, you will see "UseOriginalReason" in the dropdown list.
3) Save it.
4. Create a new work item, and now you can keep the original reason.
In additional, it is needed to copy CustomWitControl.dll and CustomWitControl.wicc to each client PC.
If there is anything unclear, please let me known.
Best Regards,
Ruiz
Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread. Sincerely, Ruiz Yi- Marked As Answer byBill2010 Monday, November 09, 2009 6:31 PM
- Hello Bill,
Is this issue resolved? Thanks.
Hongye Sun [MSFT]
MSDN Subscriber Support in Forum
If you have any feedback on our support, please contact msdnmg @ microsoft.com
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.


