Converting Inline back to WatermarkTextBox - wpf

I am using the WPF toolkit for its WatermarkTextBox control.
My application dynamically concatenates text strings and placeholders for a user to fill in the blanks.
foreach(var e in elements)
{
if (isText)
{
LetterText.Inlines.Add(new Run
{
Text = e,
BaselineAlignment = BaselineAlignment.Center
});
}
else
{
LetterText.Inlines.Add(new WatermarkTextBox
{
Watermark = e
});
}
isText = !isText;
}
This works quite well, but my problem occurs when I want to reassemble the text:
foreach(var inline in LetterText.Inlines)
{
if (inline.GetType() == typeof(Run))
{
sb.Append(((Run)inline).Text);
}
else if (inline.GetType() == typeof(WatermarkTextBox))
{
var wtb = inline as WatermarkTextBox;
sb.Append(wtb.Text);
}
}
This fails at compile time with 'Cannot convert Inline to WatermarkTextBox' (without the else clause, the conversion from Inline to Run works fine).
How can I get the text from the WatermarkTextBox?

This did the trick:
if (inline.GetType() == typeof(Run))
{
sb.Append(((Run)inline).Text);
}
else if (inline.GetType() == typeof(InlineUIContainer))
{
var container = inline as InlineUIContainer;
var wtb = container.Child as WatermarkTextBox;
if (wtb !=null)
sb.Append(wtb.Text);
}
I don't know why the InlineUIContainer does not also get implicitly created for Run elements

Related

I am new to Apex development and trying to compile this code but failing

public class InstanceTriggerHandler {
public static void createInstanceHistoryRecord(Map<ID,Instance__c> newMap, Map<ID,Instance__c> oldMap) {
List<Instance_History__c > listOfIntHistoryToCreate = new List<Instance_History__c >();
List<Schema.FieldSetMember> trackedFields = SObjectType.Instance__c.FieldSets.Case_View.getFields();
if (trackedFields.isEmpty()) return;
for(Instance__c ins:newMap.values()) {
for (Schema.FieldSetMember fst : trackedFields) {
String fieldName = fst.getFieldPath();
String fieldLabel = fst.getLabel();
Instance__c oldInstance = (oldMap != null) ? oldMap.get(ins.id) : new Instance__c();
if (ins.get(fieldName) != oldInstance.get(fieldName)) {
String newValue = String.valueOf(ins.get(fieldName));
String oldValue = String.valueOf(oldInstance.get(fieldName));
if (oldValue != null && oldValue.length()>255) {
oldValue = oldValue.substring(0,255);
}
if (newValue != null && newValue.length()>255) {
newValue = newValue.substring(0,255);
}
final Instance_History__c instanceHistory = new Instance_History__c();
instanceHistory.Field__c = fieldLabel;
instanceHistory.Instance__c = ins.Id;
instanceHistory.Field_API__c = fieldName;
instanceHistory.Original_Value__c = oldValue;
instanceHistory.New_Value__c = newValue;
listOfIntHistoryToCreate.add(instanceHistory);
}
}
}
if(!listOfIntHistoryToCreate.isEmpty()) {
insert listOfIntHistoryToCreate;
}
}
}
Apex is giving me an error.
"Invalid type: Schema.Instance_History".
I already checked my custom object and it indeed has double underscores in code everywhere it is referenced. Can someone help?
Field history objects for custom objects need 2 underscores, try Instance__History. Probably easiest for you is to use http://workbench.developerforce.com/ to see all objects? You ever used "describe" operations?
https://help.salesforce.com/s/articleView?id=sf.tracking_field_history.htm&type=5
Salesforce stores an object’s tracked field history in an associated
object called StandardObjectNameHistory or CustomObjectName__History.
For example, AccountHistory represents the history of changes to the
values of an Account record’s fields. Similarly,
MyCustomObject__History tracks field history for the MyCustomObject__c
custom object.
Schema.SObjectType.Instance__c.FieldSets.Case_View.getFields();

How to pass an Array of Expr (expressions) to Haxe Macro?

I'm basically trying to create a macro that automatically generates an if/else if chain by supplying one common outcome statement for all conditions.
This is what I've tried so far (modified the code just to show as an example):
import haxe.macro.Expr;
class LazyUtils {
public macro static function tryUntilFalse( xBool:Expr, xConds:Array<Expr> ) {
var con1, con2, con3, con4, con5;
/*
* Here's a switch to handle specific # of conditions, because for-loops
* don't seem to be allowed here (at least in the ways I've tried so far).
*
* If you know how to use for-loop for this, PLEASE do tell!
*/
switch(xConds.length) {
case 1: {
con1 = conds[0];
return macro {
if (!$con1) $xBool;
}
}
case 2: {
con1 = conds[0];
con2 = conds[1];
return macro {
if (!$con1) $xBool;
else if (!$con2) $xBool;
}
}
case 3: {
con1 = conds[0];
con2 = conds[1];
con3 = conds[2];
return macro {
if (!$con1) $xBool;
else if (!$con2) $xBool;
else if (!$con3) $xBool;
}
}
// ... so on and so forth
}
return macro { trace("Unhandled length of conditions :("); };
}
}
Then, in theory it could be used like this:
class Main {
static function main() {
var isOK = true;
LazyUtils.tryUntilFalse( isOK = false, [
doSomething(),
doSomethingElse(), //Returns false, so should stop here.
doFinalThing()
]);
}
static function doSomething():Bool {
// ???
return true;
}
static function doSomethingElse():Bool {
// ???
return false;
}
static function doFinalThing():Bool {
return true;
}
}
Which should generate this condition tree:
if (!doSomething()) isOK = false;
else if (!doSomethingElse()) isOK = false;
else if (!doFinalThing()) isOK = false;
Alternatively, I suppose it could output this instead:
if(!doSomething() || !doSomethingElse() || !doFinalThing()) isOK = false;
Looking back at this now, true - it may not make much sense to write a whole macro to generate code that would be easier to type out in it's raw format.
But for the sake of learning about macros, does anyone know if multiple expressions can be passed in an Array<Expr> like I tried in the above code sample?
You probably couldn't get the xConds argument to behave like you expected because the final argument of an expression macro with the type Array<Expr> is implicitly a rest argument. That means you ended up with an array that contained a single EArrayDecl expression. This can be fixed by simply omitting the [].
Regarding generating the if-else-chain - let's take a look at EIf:
/**
An `if(econd) eif` or `if(econd) eif else eelse` expression.
**/
EIf( econd : Expr, eif : Expr, eelse : Null<Expr> );
The chain can be thought of as a singly linked list - the eelse if the first EIf should reference the next EIf and so forth, until we stop with eelse = null for the last EIf. So we want to generate this for your example (pseudo-code):
EIf(doSomething(), isOk = false, /* else */
EIf(doSomethingElse, isOk = false, /* else */
EIf(doFinalThing(), isOk = false, null)
)
)
Recursion works well for this.
Typically it's more convenient to work with reification than raw expressions like I do here, but I'm not sure the former is really possible when dynamically generating expressions like this.
import haxe.macro.Context;
import haxe.macro.Expr;
class LazyUtils {
public macro static function tryUntilFalse(setBool:Expr, conditions:Array<Expr>):Expr {
return generateIfChain(setBool, conditions);
}
private static function generateIfChain(eif:Expr, conditions:Array<Expr>):Expr {
// get the next condition
var condition = conditions.shift();
if (condition == null) {
return null; // no more conditions
}
// recurse deeper to generate the next if
var nextIf = generateIfChain(eif, conditions);
return {
expr: EIf(condition, eif, nextIf),
pos: Context.currentPos()
};
}
}
And Main.hx (mostly unchanged):
class Main {
static function main() {
var isOK = true;
LazyUtils.tryUntilFalse(isOK = false,
!doSomething(),
!doSomethingElse(), //Returns false, so should stop here.
!doFinalThing()
);
}
static function doSomething():Bool {
trace("doSomething");
return true;
}
static function doSomethingElse():Bool {
trace("doSomethingElse");
return false;
}
static function doFinalThing():Bool {
trace("doFinalThing");
return true;
}
}
To keep things simple I inverted the function call arguments with ! at the call site instead of handling that in the macro.
You can use -D dump=pretty to generate AST dumps and check what code is being generated. Here's the result:
if ((! Main.doSomething()))isOK = false else if ((! Main.doSomethingElse()))isOK = false else if ((! Main.doFinalThing()))isOK = false;

Use renderer for ExtJS form field

I'm trying to create a PercentField component that extends textfield for use on ExtJS forms. The behavior I'm looking for is for the field to display percent values, e.g. 25% or 400%, but have the underlying value when the user is editing the field or the form is being submitted be a decimal, e.g. .25 or 4.
I've succeeded in getting this working by using a renderer in a grid column, (Here's a fiddle) but it doesn't look like textfield has a renderer property for using the field in basic forms. I've looked at the rawToValue and valueToRaw methods, but they don't seem to be quite what I'm looking for. Any advice?
As far as I know, there's no possibility of template for form fields. That would require to flip the input element and display a div or something, on focus and blur. That would be doable, but that implies some fine tuned CSS.
A simpler option is to implement custom valueToRaw and rawToValue methods, and let Ext handles the value lifecycle (which is really the complicated part). You'll still have to change the raw value on focus and blur, but that remains pretty straightforward.
Here's an example you can build upon (see fiddle):
Ext.define('My.PercentTextField', {
extend: 'Ext.form.field.Text',
onFocus: function() {
this.callParent(arguments);
var v = this.getValue();
if (Ext.isNumeric(v)) {
this.setRawValue(this.rawToValue(v));
}
},
onBlur: function() {
this.callParent(arguments);
var v = this.getValue();
if (Ext.isNumeric(v)) {
this.setRawValue(this.valueToRaw(v));
}
},
valueToRaw: function(v) {
return Ext.isEmpty(v)
? ''
: v * 100 + ' %';
},
rawToValue: function(v) {
// cast to float
if (!Ext.isEmpty(v)) {
var pcRe = /^(\d*(?:\.\d*)?)\s*%$/,
dcRe = /^\d*(?:\.\d*)?$/,
precision = 2,
floatValue,
match;
if (match = dcRe.test(v)) { // decimal input, eg. .33
floatValue = v * 1;
} else if (match = pcRe.exec(v)) { // % input, eg. 33 %
floatValue = match[1] / 100;
} else {
// invalid input
return undefined;
}
floatValue = Number.parseFloat(floatValue);
if (isNaN(floatValue)) {
return undefined;
} else {
return floatValue.toFixed(precision);
}
} else {
return undefined;
}
}
});

ASP.NET Entity Framework Update SQL set int value to 0

I have a SQL column as an int data type.
I'm trying to update en entry using Entity Framework, setting it's value to 0 but it does not get updated. I also don't get an error when Submitting Changes... Odd. Well I changed the Tag Name and set the count to 0, the name got updated but the count was not modified
Any ideas?
Thanks in advance
Code Snipet:
Add Tag - up the tag count:
Tag tag = _tagsRepository.GetTagByName(TagName);
if (tag == null)
{
tag = new Tag();
tag.CreateDate = DateTime.Now;
tag.Name = TagName;
tag.Count = 1;
}
else
{
tag.Count += 1;
}
tag = _tagsRepository.SaveTag(tag);
Remove tag from an item, update the tag count
Tag tag = _tagsRepository.GetTagByName(TagName);
if (tag != null)
{
tag.Count -= 1;
}
tag = _tagsRepository.SaveTag(tag);
GetTagByName Method
public Tag GetTagByName(string Name)
{
Tag result = null;
using (ISADataContext dc = conn.GetContext())
{
result = dc.Tags.Where(t => t.Name == Name).FirstOrDefault();
}
return result;
}
SaveTag Method
public Tag SaveTag(Tag tag)
{
using (ISADataContext dc = conn.GetContext())
{
if (tag.TagID > 0)
{
dc.Tags.Attach(new Tag { TagID = tag.TagID });
dc.Tags.ApplyCurrentValues(tag);
}
else
{
dc.Tags.AddObject(tag);
}
dc.SaveChanges();
}
return tag;
}
Workaround:
using (ISADataContext dc = conn.GetContext())
{
if (tag.TagID > 0)
{
if (tag.Count == 0)
{
Tag t = dc.Tags.Where( tt=> tt.TagID == tag.TagID).First();
t.Count = 0;
}
else
{
dc.Tags.Attach(new Tag { TagID = tag.TagID });
dc.Tags.ApplyCurrentValues(tag);
}
}
else
{
dc.Tags.AddObject(tag);
}
dc.SaveChanges();
}
return tag;
You shouldn't wrap your DataContext in using statements in your scenario. Doing this means that you're retrieving the object in one context and trying to save the existing object in a new context. This means that when you're trying to save in the second context, it has no idea that the object already exists in the database.
I ran into the same problem as yours - every other value except 0 works fine. Can we get some solution to this?
EDIT: After some research, I found a way to fix this. You have to modify this line:
dc.Tags.Attach(new Tag { TagID = tag.TagID });
In the stub object, add the problematic property (in your case Count) and set its value to something that is never possible in the db, for example -2. In this way, the EF context will also compare the count value of the attached object and will always know there is a difference. So your line becomes:
dc.Tags.Attach(new Tag { TagID = tag.TagID, Count = -2 });
I am not sure if this will work every time, but for now it seems to do the job.

How can I delete a hyperlink in a Silverlight RichTextBox?

I have a RichTextBox that the user can edit to create a hyperlink (in my case to another page with the document rather than an external URL). Having successfully created the link I now need to be able to remove it.
I have code that identifies that I've got a hyperlink in the current selection:
TextSelection linkText = richTextBox.Selection;
if (linkText != null && !string.IsNullOrWhiteSpace(linkText.Text))
{
XElement root = XElement.Parse(linkText.Xaml);
XNamespace ns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
XElement linkElement = root.Element(ns + "Paragraph").Element(ns + "Hyperlink");
if (linkElement != null)
{
// Get here if have a Hyperlink. How do I remove or update?
}
}
However, I'm now stuck on the bit that goes inside the if test. How do I find the hyperlink so I can remove it completely?
My code for setting up the hyperlink is:
TextSelection linkText = richTextBox.Selection;
var hyperlink = new Hyperlink();
hyperlink.Inlines.Add(linkText.Text);
if (!String.IsNullOrEmpty(selectedTopic)) // A string holding the link target
{
// Setup hyperlink here
}
linkText.Insert(hyperlink);
I've managed to work out how to update the hyperlink:
foreach (var block in richTextBox.Blocks)
{
Paragraph p = block as Paragraph;
foreach (var inline in p.Inlines)
{
var hyperlink = inline as Hyperlink;
if (hyperlink != null && hyperlink.NavigateUri.AbsoluteUri.Contains(currentLink))
{
hyperlink.NavigateUri = new Uri(newLink);
}
}
}
I could use the same approach to delete the hyperlink, but how do I convert the Hyperlink to a normal Inline?
Looks like you are getting close you just need to hold a reference to the link then use Remove. Something like the following (I like to use Linq to make things a little more succinct):-
foreach (var p in richTextBox.Blocks.OfType<Paragraph>())
{
var hyperlink = p.Inlines.OfType<HyperLink>()
.FirstOrDefault(hl => hl.NavigateUri.AbsoluteUri.Contains(currentLink));
if (hyperlink != null)
{
p.Inlines.Remove(hyperlink);
break;
}
}
Edit: Want to leave the content of hyperlink in place? (i.e., just remove the wrapping hyperlink),
foreach (var p in richTextBox.Blocks.OfType<Paragraph>())
{
var hyperlink = p.Inlines.OfType<HyperLink>()
.FirstOrDefault(hl => hl.NavigateUri.AbsoluteUri.Contains(currentLink));
if (hyperlink != null)
{
int index = p.Inlines.IndexOf(hyperlink);
Span span = new Span();
foreach (var inline in hyperlink.Inlines.ToArray())
{
hyperlink.Inlines.Remove(inline);
span.Inlines.Add(inline);
}
// You may need code here to preserve the Font properties etc from hyperlink to span.
p.Inlines[index] = span;
break;
}
}

Resources