Jokes can become reality...
Check this out... a designer protests a design challenge of updating a hearse -- and it backfired in the worst way:
DOA Design at Design Matters.
Check this out... a designer protests a design challenge of updating a hearse -- and it backfired in the worst way:
DOA Design at Design Matters.
I've blogged about IValueConverters and WPF many times in the past:
I've got another. This new one may seem a bit obscure, but it has proven useful. Here's what I wanted to do: conditionally, based on the enabled state of a button, swap between two different images, without special code, and without needing to use a style or a template; ideally the solution would not require an events or triggers.
So, I created the ConditionalStringConverter:
[ValueConversion(typeof(Boolean), typeof(string))] public class ConditionalStringConverter :IValueConverter { /// <summary> /// Converts a bound boolean value to a conditional string value. /// </summary> /// <param name="value">The boolean value (as a Boolean)</param> /// <param name="targetType">(ignored)</param> /// <param name="parameter">A string of the following format: /// {"value" Matches against this Boolean Value: True or False}?
{Return This Value if matches}:{Return this value if no match} /// For example: True?BackBtn.png:BackBtnDisabled.png /// If the bound boolean property is True, this converter returns
BackBtn.png. If False, it returns BackBtnDisabled.png /// </param> /// <param name="culture">ignored</param> /// <returns></returns> public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture) { if (string.IsNullOrEmpty((string) parameter)) { throw new ArgumentNullException(
"Converter Parameter must be specified when using
the ConditionalStringConverter."); }string[] condition = ((string)parameter).Split('?');
if (condition.Length != 2) {
throw new ArgumentOutOfRangeException(
"Converter Parameter improperly specified in ConditionalStringConverter."); }string[] values = condition[1].Split(':');
if (values.Length != 2) {
throw new ArgumentOutOfRangeException(
"Converter Parameter improperly specified in ConditionalStringConverter."); }
if (value is Boolean) {
bool compareValue = Boolean.Parse(condition[0]);if ((bool)value == compareValue) {
return values[0];
}
else {
return values[1];
}
}
else
{
throw new ArgumentException(
"ConditionalStringConverter converts only booleans", "value");
}
}public object ConvertBack(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Before I walk through my simple solution, here it is in use:
<Button
x:Name="btnBack"
DockPanel.Dock="Top"
IsEnabled="{Binding Path=IsNotAtRoot}"
Click="btnBack_Click" Style="{DynamicResource ImageButtonStyle}">
<StackPanel
Orientation="Horizontal">
<Image
Source="{Binding Path=IsEnabled,
Converter={StaticResource conditionalConverter},
ConverterParameter=True?BackBtn.png:BackBtnDisabled.png,
RelativeSource={RelativeSource AncestorType={x:Type ButtonBase},
Mode=FindAncestor}}"
Height="24"
Width="24" />
<TextBlock
VerticalAlignment="Center"><Run Text="Back"/></TextBlock>
</StackPanel>
</Button>
The important part of the example that uses the new value converter is right here:ConverterParameter=True?BackBtn.png:BackBtnDisabled.png,
Based on the boolean binding, the value converter compares the value of the binding to the boolean value specified as the converter parameter. If the values match, the value converter returns the first value. If it does not, it returns the second value. If you're familiar with the C# conditional operator (?:), this should be familiar syntax.To make the image swap, I resorted to using a RelativeSource binding with an AncestorType of ButtonBase.
What's nice about this solution is that the Image's Source parameter accepts the String file name and happily converts it as necessary to the image (which in my application is a resource).And no, I'm not done with the button yet -- so it's a bit ugly.
Binding's in WPF can make quick work of getting values from object properties.
I've created a class with a property:
public XmlElement SelectedVideo { get { return _selectedVideo; } }
This Property is of Type XmlElement. The XmlElement it binds to typically is structured like this:
<Video title="Anonymous Methods" source="Data\anonmethods.wmv"
timecode="00:01:00" />
With a tiny bit of binding magic, I can easily fetch the title from the element and display it within a textblock:
<TextBlock Text="{Binding Path=SelectedVideo.Attributes[title].Value, Mode=OneWay}"
Since this is a read-only XmlElement, I've set the Mode to be OneWay (as it can't be updated via the TextBlock). Since the element may change, I need to use OneWay binding. OneTime wouldn't work as the SelectedVideo element may change.
The slick part is that the binding syntax allows me to use the indexer on the Attributes object. The only odd thing is that it doesn't need any quotation marks or delimiters.
I'm not using XPath bindings here because I'm not binding directly to an Xml Data Provider in my application (not always at least).
When a web site is interested in your personal information -- just for the purposes of interacting with them, how much of it do you provide honestly? (Of course, there are perfectly legit reasons for needing things like your address and phone if you're placing an order).
Imagine if every department store you walked in required you to fill out a form with your personal information, provide a password, and sign up for a few newsletters? Wouldn't you shop elsewhere?
What If every blog you went to required the following to add a comment:
Would you ever bother? Or would you provide mostly fake-data?
I'm amazed by the number of members on zdnet (judging by the comments left on some of the blog posts). My interest in adding a comment this morning dropped to zero when I was asked to give out all of this information.
"Required fields are marked with an asterisk (*)." It should have been inverted: non-required fields are marked with an asterisk. The only field that isn't required practically speaking is a second address line.
But, there's more! You get the privilege of being added to their important newsletters!
And, so that you might miss it, down at the bottom of the subscription list (after a long list of unchecked newsletters):
They've handily pre-checked one for "offers from our premier enterprise sponsors." Otherwise known as opt-in spam.
Finally, to sign up you must agree to their privacy policy and "terms and conditions" -- which total 4,863 words.
No thanks ZdNet.