@lise wrote:
Hello Walter
I have a NodeData class with a property called Icon, and a property called Status. The icon has a private setter and a public getter and is automatically set when the property Status gets set.
public class MyNodeData : GraphLinksModelNodeData<string> { private PartStatus _status; public PartStatus Status { get { return this._status; } set { PartStatus oldStatus = this._status; this._status = value; this.IconName = this.IconName; // changes the icon depending on status RaisePropertyChanged("Status", oldStatus, value); } } private string _iconName; public string IconName { get { return this._iconName; } set { // grabs icon from cache depending on status, which is not interesting here BitmapImage icon = ... BitmapImage oldIcon = this.Icon; this.Icon = icon; RaisePropertyChanged("Icon", oldIcon, icon); this._iconName = value; } } public BitmapImage Icon { get; private set; } // various other properties ... }
with PartStatus being the following enum:
public enum PartStatus { Default, Selected, Unselectable, Disabled }
The xaml looks like this:
<Style x:Key="StatusStackPanelStyle" TargetType="StackPanel"> <Style.Triggers> <DataTrigger Binding="{Binding Path=Data.Status}" Value="{x:Static style:PartStatus.Default}"> <Setter Property="go:Part.Selectable" Value="{Binding Path=Data.IsSelectable}" /> </DataTrigger> <DataTrigger Binding="{Binding Path=Data.Status}" Value="{x:Static style:PartStatus.Selected}"> <Setter Property="go:Part.Selectable" Value="{Binding Path=Data.IsSelectable}" /> </DataTrigger> <DataTrigger Binding="{Binding Path=Data.Status}" Value="{x:Static style:PartStatus.Disabled}"> <Setter Property="go:Part.Selectable" Value="False" /> </DataTrigger> <DataTrigger Binding="{Binding Path=Data.Status}" Value="{x:Static style:PartStatus.Unselectable}"> <Setter Property="go:Part.Selectable" Value="False" /> </DataTrigger> </Style.Triggers> </Style> <!-- I am leaving out all attributes of no interest as there are quite a lot --> <DataTemplate x:Key="MyNodeTemplate"> <StackPanel Style="{StaticResource StatusStackPanelStyle}"> <go:SpotPanel> <go:NodePanel> <StackPanel> <!-- this grid exists so an image can be displayed UniformToFill and at the same time be centered --> <Grid> <Image Source={Binding Path=Data.Icon} /> </Grid> </StackPanel> </go:NodePanel> <!-- just like the StatusStackPanelStyle, this style sets Stroke, LinkableFrom/To and Cursor based on the Node's status --> <Ellipse Style="{StaticResource StatusPortStyle}" /> <!-- there are many more Ports, which only differ in position ---> </go:SpotPanel> <TextBlock Text="{Binding Path=Data.Text}" /> <!-- some more elements to show additional information --> </StackPanel> </DataTemplate>
When I select a node in the diagram, its
Status
gets set toPartStatus.Selected
obviously. When I try to draw a link but cancel the operation, anInvalidOperationException
gets thrown, which shows nothing but "Icon" as error message but only if there was a change inStatus
recently. The linking operation itself does not change theStatus
. Checking the stack trace and overriding theChangeDataValue
function ofGraphLinksModel
showed me that theGraphLinksModel
tries to reset the changed properties of the node, which in case of theIcon
property is invalid of course due to the private setter. I solved this by checking for the property name for "Icon" in the functionChangeDataValue
before calling the base function but the question is, as the incorrect linking operation doesn't change the node'sStatus
and theStatus
change happened beforehand and has nothing to do with the linking operation, why is it actually trying to revert these properties?
Posts: 2
Participants: 2