我的View中有一个TreeView,它绑定到ViewModel中的根<?php
error_reporting(0);
$salt = "eCwWELxi"; # salt value need to be picked from your database
$amount = $_POST["amount"]; # amount need to be picked up from your database
$reverseHash = generateReverseHash();
if ($_POST["hash"] == $reverseHash) {
# transaction is successful
# do the required javascript task
echo("Transaction Success & Verified");
AndroidSuccess($_POST["amount"]);
}
else{
# transaction is tempered
# handle it as required
echo("<br>");
echo "\nInvalid transaction";
}
# For Android Success
function AndroidSuccess($input) {
echo '<script type="text/javascript">';
echo 'PayU.onSuccess("Amount =" +'.$_POST["amount"].')';
echo "</script>";
}
# Function to generate reverse hash
function generateReverseHash() {
global $salt;
global $amount;
if ($_POST["additional_charges"] != null) {
$reversehash_string = $_POST["additional_charges"] . "|" . $salt . "|" . $_POST["status"] . "||||||" . $_POST["udf5"] . "|" . $_POST["udf4"] . "|" . $_POST["udf3"] . "|" . $_POST["udf2"] . "|" . $_POST["udf1"] . "|" .
$_POST["email"] . "|" . $_POST["firstname"] . "|" . $_POST["productinfo"] . "|" . $amount . "|" . $_POST["txnid"] . "|" . $_POST["key"] ;
}
else{
$reversehash_string = $salt . "|" . $_POST["status"] . "||||||" . $_POST["udf5"] . "|" . $_POST["udf4"] . "|" . $_POST["udf3"] . "|" . $_POST["udf2"] . "|" . $_POST["udf1"] . "|" .
$_POST["email"] . "|" . $_POST["firstname"] . "|" . $_POST["productinfo"] . "|" . $amount . "|" . $_POST["txnid"] . "|" . $_POST["key"] ;
}
// echo($reversehash_string);
$reverseHash = strtolower(hash("sha512", $reversehash_string));
return $reverseHash;
}
列表中。那些根Node
可以有子Node
。所有节点都具有相同的类型,并具有属性Nodes
,该属性绑定到相应IsSelected
中包含的IsChecked
的{{1}}的{{1}}依赖项属性。 CheckBox
已将TreeViewItem
设置为CheckBox
。
IsThreeState
false
是实现public class Node : PropertyChangedBase, INode
{
private bool? _isSelected;
private IList<INode> _nodes;
private INode _parent;
public Node()
{ }
public bool? IsSelected
{
get { return _isSelected; }
set
{
if (_SetField(ref _isSelected, value))
{
_OnIsSelectedChanged();
}
}
}
public IList<INode> Nodes
{
get { return _nodes; }
set { _SetField(ref _nodes, value); }
}
public INode Parent
{
get { return _parent; }
set { _SetField(ref _parent, value); }
}
private void _OnIsSelectedChanged()
{
if (IsSelected.HasValue)
{
if (IsSelected.Value)
{
if (Parent != null)
{
// Set IsSelected on all parenting nodes to:
// - true, if all of their immediate child packages have been selected
// - null, else
}
if (Nodes != null && Nodes.Count > 0)
{
// Prevent running this method again by circumventing setting the property
_SetField(ref _isSelected, null);
}
}
else
{
if (Parent != null)
{
// Set IsSelected of the parent to null
}
if (Nodes != null)
{
// Set IsSelected = false on all child nodes
}
}
}
else if (Parent != null)
{
// Set IsSelected on all parenting nodes to:
// - true, if all of their immediate child packages have been selected
// - null, else
}
}
}
的基类。它是在this SO answer之后设计的。如果设置值实际发生更改,则PropertyChangedBase
返回INotifyPropertyChanged
并通知属性更改。
如果用户单击CheckBox,则所做的更改还将传播父节点的(直到根节点)_SetField(ref object, object)
属性,也传播到子节点的true
属性。所有属性的传播完成后,我要触发一个事件。但是仅当没有其他节点将被更改时。然后,我想在ViewModel中做一些事情,这会花费一些时间,因此如果事件随每个更改的属性一起触发,这将是性能下降的原因。
该行为应为以下情况:
IsSelected
设置为IsSelected
或IsSelected
,则如果不是节点的所有同级节点{,则父节点的true
设置为null
。将{1}}设置为IsSelected
或null
(然后将其传播到树上)。IsSelected
设置为true
或null
,则如果节点的所有兄弟姐妹的{{ 1}}设置为IsSelected
或true
(然后传播到树上)。null
设置为IsSelected
,则其所有直接子节点的true
也都设置为IsSelected
(然后传播到树上)。 true
的节点意味着并非所有其直接子节点都已被选择。那么,只有在更改了最后一个节点之后,如何才能实现触发PropertyChanged事件(或我要实现的另一个事件)?
答案 0 :(得分:1)
我最终做了Alexandru的建议。
我介绍了两个事件IsSelectedChangedPropagationStarted
和IsSelectedChangedPropagationCompleted
,第一个在处理选择之前引发,第二个在完成时引发。该类现在看起来与此类似:
public class Node : PropertyChangedBase, INode
{
// #### Attributes
private bool? _isSelected;
private IList<INode> _nodes;
private INode _parent;
// #### Constructor
public Node()
{ }
// #### Properties
public bool? IsSelected
{
get { return _isSelected; }
set
{
if (_SetField(ref _isSelected, value))
{
_OnIsSelectedChanged();
}
}
}
public IList<INode> Nodes
{
get { return _nodes; }
set { _SetField(ref _nodes, value); }
}
public INode Parent
{
get { return _parent; }
set { _SetField(ref _parent, value); }
}
// #### Events
public event EventHandler IsSelectedChangedPropagationStarted;
public event EventHandler IsSelectedChangedPropagationCompleted;
// #### Instance Methods
private void _OnIsSelectedChanged()
{
IsSelectedChangedPropagationStarted?.Invoke(this, EventArgs.Empty);
if (IsSelected.HasValue)
{
if (IsSelected.Value)
{
RecursivelySetAllParents();
if (Nodes != null && Nodes.Count > 0)
{
// Prevent running this method again by circumventing setting the property
_SetField(ref _isSelected, null);
}
}
else
{
if (Parent != null)
{
// Set IsSelected of the parent to null
}
RecursivelySetAllChildren();
}
}
else if (Parent != null)
{
// Set IsSelected on all parenting nodes to:
// - true, if all of their immediate child packages have been selected
// - null, else
}
IsSelectedChangedPropagationCompleted?.Invoke(this, EventArgs.Empty);
}
}
通过实现自定义EventArgs
,我还可以告诉侦听器是否有任何更改,以便他们可以采取相应的行动。