Finding resource in dll instead of main application - c#

I am working on a DLL that will place two hidden buttons in a WPF application.
Clicking those buttons on the right order will raise an event.
To remove the Mouse Over effect, I created a new style. I wanted the buttons to be completely transparent.
WPF Code
SecretCode.WPF secretCode = new SecretCode.WPF(testGrid, SecretCode.WPF.Location.Bottom, 75, 4000);
secretCode.SecretCodeActivated += secretCode_SecretCodeActivated;
APP.xaml
<Style x:Key="TransparentStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border>
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid Background="Transparent">
<ContentPresenter></ContentPresenter>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
However, the issue is that I don't want to place that style on the WPF project as I want the DLL to be completely independent.
Secret Code DLL
public WPF(Grid grid, Location location, int size, int timeout)
{
Button leftButton = new Button();
leftButton.Width = size;
leftButton.Height = size;
leftButton.Margin = new Thickness(0, 0, 0, 0);
leftButton.HorizontalAlignment = HorizontalAlignment.Left;
leftButton.VerticalAlignment = location == Location.Top? VerticalAlignment.Top : VerticalAlignment.Bottom;
leftButton.Background = Brushes.Transparent;
leftButton.Style = Application.Current.FindResource("TransparentStyle") as Style;
leftButton.Click += leftPanel_Click;
grid.Children.Add(leftButton);
Button rightButton = new Button();
rightButton.Width = size;
rightButton.Height = size;
rightButton.Margin = new Thickness(0, 0, 0, 0);
rightButton.HorizontalAlignment = HorizontalAlignment.Right;
rightButton.VerticalAlignment = location == Location.Top ? VerticalAlignment.Top : VerticalAlignment.Bottom;
rightButton.Background = Brushes.Transparent;
rightButton.Style = Application.Current.FindResource("TransparentStyle") as Style;
rightButton.Click += rightPanel_Click;
grid.Children.Add(rightButton);
timeoutTimer.Interval = timeout;
timeoutTimer.Elapsed += timeoutTimer_Tick;
}
Is there any way to do that?

In some DLL:
<ResourceDictionary >
<Style x:Key="BoringButtonStyle" TargetType="{x:Type Button}">
//.....
</Style>
</ResourceDictionary>
On your application:
<Application ...>
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Globals;component/Styles/ButtonStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
And then you can use it as a DynamicResource freely:
<UserControl ...>
<Grid>
<Button style="{DynamicResource BoringButtonStyle}"/>
</Grid>
</UserControl>
An alternative way to the code in app.xaml is:
ResourceDictionary dict = new ResourceDictionary();
System.Windows.Application.LoadComponent(dict, new System.Uri("/SomeAssembly;component/SomeResourceDictionary.xaml",System.UriKind.Relative));

This is what I could comeup with for you. Hope this helps.
Use the below string in your DLL class.
private string xamlText = "<Style xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" x:Key=\"TransparentStyle\" TargetType=\"Button\">" +
"<Setter Property=\"Template\">" +
" <Setter.Value> " +
"<ControlTemplate TargetType = \"Button\">" +
"<Border>" +
"<Border.Style>" +
"<Style TargetType=\"{x:Type Border}\">" +
"<Style.Triggers>" +
"<Trigger Property = \"IsMouseOver\" Value=\"True\">" +
"<Setter Property = \"Background\" Value=\"Transparent\"/>" +
"</Trigger>" +
"</Style.Triggers>" +
"</Style>" +
"</Border.Style>" +
"<Grid Background = \"Transparent\">" +
"<ContentPresenter></ContentPresenter>" +
"</Grid>" +
"</Border>" +
"</ControlTemplate>" +
"</Setter.Value>" +
"</Setter>" +
"</Style>";
Add the following code at the top of the WPF method
var stringReader = new StringReader(xamlText);
var xmlReader = XmlReader.Create(stringReader);
var style = XamlReader.Load(xmlReader) as Style;
Next, just do like so:
leftButton.Style = style;
and
rightButton.Style = style;
I had once an extreme case I had to use such method so I pulled it out.

In general, when you create a library, you define its setting set. These settings are specified through methods. However, you need to phrase your problem in the most general way you can. You need a way to set the pattern expected (the right order), a history member to check whether the pattern is being matched and styling/class attributes. You can store the settings into an ini file or an XML or into the memory of your program or under the hood inside the DLL.

Related

Why is the Style not getting applied from code? [duplicate]

This question already has answers here:
How do you change Background for a Button MouseOver in WPF?
(6 answers)
Closed 12 months ago.
I'm trying to create a button from code and make the hover color change, for some reason the setters, etc are not getting applied. I'm pretty sure I'm either missing a step or it's something else but nothing changes, not even the color while not hovering. I'm not trying to make the button in XAML but create it in code and I know how to do it in XAML.
System.Windows.Controls.Button createPlaylist = new System.Windows.Controls.Button()
{
Height = 100,
Width = 100,
Margin = new Thickness(0,50,0,0)
};
// STYLE END //
var dt = new DataTemplate();
Style style = new Style(typeof(System.Windows.Controls.Button), createPlaylist.Style);
Trigger t = new Trigger();
t.Property = IsMouseOverProperty;
t.Value = true;
Setter setter = new Setter();
setter.Property = BackgroundProperty;
setter.Value = Brushes.Blue;
t.Setters.Add(setter);
Trigger s = new Trigger();
s.Property = IsMouseOverProperty;
s.Value = false;
Setter set = new Setter();
set.Property = BackgroundProperty;
set.Value = Brushes.Red;
s.Setters.Add(setter);
style.Triggers.Add(t);
createPlaylist.Style = style;
You have to manage the Background color of the Border within the Template of the Button, instead of just changing the Background property of the Button itself.
i.e. do the equivalent of this XAML:
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}">
<ContentPresenter/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Blue"/>
</Trigger>
</Style.Triggers>
</Style>
Something like this on code behind:
Style buttonStyle = new Style();
FrameworkElementFactory contentBorder = new FrameworkElementFactory(typeof(Border));
contentBorder.AppendChild(new FrameworkElementFactory(typeof(ContentPresenter)));
contentBorder.SetBinding(Border.BackgroundProperty, new Binding { RelativeSource = RelativeSource.TemplatedParent, Path = new PropertyPath(nameof(Background)) });
ControlTemplate templateButton = new ControlTemplate(typeof(Button)) { VisualTree = contentBorder };
buttonStyle.Setters.Add(new Setter { Property = Button.TemplateProperty, Value = templateButton });
Trigger styleTrigger = new Trigger { Property = Button.IsMouseOverProperty, Value = true };
styleTrigger.Setters.Add(new Setter { Property = Button.BackgroundProperty, Value = Brushes.Blue });
buttonStyle.Triggers.Add(styleTrigger);
createPlaylist.Style = buttonStyle;

DataGridHyperlinkColumn text color when highlighted

I have a simple WPF application which displays reddit links in a DataGrid:
Notice however that the link in the DataGridHyperlinkColumn isn't visible when a row is selected, due to the color of the link and the color of the row highlight.
What's a good way to resolve this? Change the link text color? Change the row highlight color?
If possible, please show your suggestion in terms of C# code as opposed to XAML as this application isn't using XAML. Otherwise, a XAML solution is fine; I'll just convert it to C#. :-)
For reference, here's the code used for the Title column:
var event_setter = new EventSetter()
{
Event = Hyperlink.ClickEvent,
Handler = (RoutedEventHandler)((sender, e) =>
{
System.Diagnostics.Process.Start((data_grid.SelectedItem as Link).Url);
})
};
var style = new Style();
style.Setters.Add(event_setter);
var hyperlink_column = new DataGridHyperlinkColumn()
{
Header = "Title",
Binding = new Binding("Title"),
ElementStyle = style,
Width = 600
};
data_grid.Columns.Add(hyperlink_column);
You could add an implicit Hyperlink style to your DataGrid:
const string Xaml = "<Style TargetType=\"Hyperlink\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">" +
"<Style.Triggers>" +
"<DataTrigger Binding=\"{Binding IsSelected, RelativeSource={RelativeSource AncestorType=DataGridCell}}\" Value=\"True\">" +
"<Setter Property=\"Foreground\" Value=\"White\" />" +
"</DataTrigger>" +
"</Style.Triggers>" +
"</Style>";
data_grid.Resources.Add(typeof(Hyperlink), System.Windows.Markup.XamlReader.Parse(Xaml) as Style);
data_grid.Columns.Add(hyperlink_column);
The Selector.IsSelected property of DataGridHyperLink Column can be used and when the selection on particular item changes you can update the style with trigger.
<DataGridHyperlinkColumn.CellStyle>
<Style TargetType="{x:Type Hyperlink}">
<Setter Property="Foreground" Value="Blue"/>
<Style.Triggers>
<Trigger Property="Selector.IsSelected" Value="True">
<Trigger.Setters>
<!--change the value for the property based on your needs-->
<Setter Property="Foreground" Value="Yellow"/>
</Trigger.Setters>
</Trigger>
</Style.Triggers>
</Style>
</DataGridHyperlinkColumn.CellStyle>
Pure XAML solution:
<DataGrid>
<DataGrid.Resources>
<Style TargetType="{x:Type Hyperlink}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=DataGridCell}}"
Value="True">
<DataTrigger.Setters>
<Setter Property="Foreground" Value="Yellow"/>
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridHyperlinkColumn Width="180"
Header="Url"
Binding="{Binding Path=Uri, Mode=OneWay}" />
</DataGrid.Columns>
</DataGrid>
Here's a version of the answer provided by #mm8 converted from XAML to C#:
var data_trigger = new DataTrigger()
{
Binding = new Binding()
{
Path = new PropertyPath("IsSelected"),
RelativeSource = new RelativeSource() { AncestorType = typeof(DataGridCell) }
},
Value = true
};
data_trigger.Setters.Add(new Setter(ForegroundProperty, new SolidColorBrush(Colors.White)));
var style = new Style(typeof(Hyperlink));
style.Triggers.Add(data_trigger);
data_grid.Resources.Add(typeof(Hyperlink), style);
Here's a version of the answer provided by #mm8 converted from XAML to C# which uses some extension methods to avoid intermediate variables:
data_grid.Resources.Add(
typeof(Hyperlink),
new Style(typeof(Hyperlink))
.AddTrigger(
new DataTrigger()
{
Binding = new Binding()
{
Path = new PropertyPath("IsSelected"),
RelativeSource = new RelativeSource() { AncestorType = typeof(DataGridCell) }
},
Value = true
}
.AddSetter(new Setter(ForegroundProperty, new SolidColorBrush(Colors.White)))));

XamDataGrid - How to create a DataRecordPresenterStyle DataTrigger from C# code

I am trying to do this:
<Style TargetType="{x:Type igDP:DataRecordPresenter}">
<Style.Triggers>
<DataTrigger Binding="{Binding DataItem.IsOnChart}" Value="true">
<Setter Property="Opacity" Value="1"/>
</DataTrigger>
<DataTrigger Binding="{Binding DataItem.IsOnChart}" Value="false">
<Setter Property="Opacity" Value="0.5"/>
</DataTrigger>
</Style.Triggers>
</Style>
From C#:
Style _DataRecordPresenterStyle = new Style(typeof(DataRecordPresenter));
_DataRecordPresenterStyle.Setters.Add(new Setter(DataRecordPresenter.OpacityProperty, 1));
var _DataTrigger = new DataTrigger() { Binding = new Binding("DataItem.IsOnChart"), Value = true };
_DataTrigger.Setters.Add(new Setter(DataRecordPresenter.OpacityProperty, 1));
_DataRecordPresenterStyle.Triggers.Add(_DataTrigger);
_DataTrigger = new DataTrigger() { Binding = new Binding("DataItem.IsOnChart"), Value = false };
_DataTrigger.Setters.Add(new Setter(DataRecordPresenter.OpacityProperty, 0.5));
_DataRecordPresenterStyle.Triggers.Add(_DataTrigger);
_Grid.FieldLayoutSettings.DataRecordPresenterStyle = _DataRecordPresenterStyle;
But when I bind the data to the grid I get the error:
Default Unhandled exception: Exception has been thrown by the target of an invocation.
The data does have the field, it's type is a bool and the value is true on all records.
What am I doing wrong here?
Thanks for your time.
"Exception has been thrown by the target of an invocation" doesn't say much. You should check the message of the InnerException. I also assume that you have verified that the Style itself works if you use it in your XAML markup.
The recommended way of creating a Style programmtically is to use the XamlReader class and parse XAML. Try this:
string xaml = "<Style xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" " +
"xmlns:igDP=\"clr-namespace:Infragistics.Windows.DataPresenter;assembly=InfragisticsWPF4.DataPresenter.v12.1\" " +
"TargetType=\"{x:Type igDP:DataRecordPresenter}\">" +
"<Style.Triggers>" +
"<DataTrigger Binding=\"{Binding DataItem.IsOnChart}\" Value=\"true\">" +
"<Setter Property=\"Opacity\" Value=\"1\"/>" +
"</DataTrigger>" +
"<DataTrigger Binding=\"{Binding DataItem.IsOnChart}\" Value=\"false\">" +
"<Setter Property=\"Opacity\" Value=\"0.5\"/>" +
"</DataTrigger>" +
"</Style.Triggers>" +
"</Style>";
Style style = System.Windows.Markup.XamlReader.Parse(xaml) as Style;
style.Seal();
You may have to change "InfragisticsWPF4.DataPresenter.v12.1" to the actual name of the assembly in which the DataRecordPresenter class is defined.

WPF/XAML How to specify the assembly to load the resource from?

I'm working on a WPF class library, not an application. Here is an example of a Label I'm making in c# and I'd like to "style" it using XAML.
private void CreateElement(int i)
{
UIElementOut[i] = new Label();
var uiElement = (Label)UIElementOut[i];
uiElement.HorizontalAlignment = HorizontalAlignment.Center;
uiElement.VerticalAlignment = VerticalAlignment.Center;
uiElement.FontFamily = new FontFamily(FFontInput[i]);
uiElement.FontSize = Convert.ToDouble(FontSizeIn[i]);
uiElement.Content = TextIn[i];
Brush BgBrushColor = new SolidColorBrush(RGBAToMediaColor(FBgCol[i]));
Brush FgBrushColor = new SolidColorBrush(RGBAToMediaColor(FFgCol[i]));
uiElement.Background = BgBrushColor;
uiElement.Foreground = FgBrushColor;
Uri uri = new Uri("Styles/LabelStyle.xaml", UriKind.Relative);
StreamResourceInfo info = Application.GetContentStream(uri);
System.Windows.Markup.XamlReader reader = new System.Windows.Markup.XamlReader();
ResourceDictionary myResourceDictionary = (ResourceDictionary)reader.LoadAsync(info.Stream);
Application.Current.Resources.MergedDictionaries.Add(myResourceDictionary);
Style myLabelStyle = myResourceDictionary["LabelStyle"] as Style;
uiElement.Style = myLabelStyle;
}
For this I have ressourcedictionnary containing my LabelStyle, everything is compiling without problem.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1">
<Style x:Key="LabelStyle" TargetType="{x:Type Label}">
<Setter Property="Height" Value="53" />
<Setter Property="Width" Value="130" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Margin" Value="99,71,0,0" />
<Setter Property="VerticalAlignment" Value= "Top" />
<Setter Property="Foreground" Value="#FFE75959" />
<Setter Property="FontFamily" Value="Calibri" />
<Setter Property="FontSize" Value="40" />
</Style>
but when I use my dll later on, the style is not applied and I have this error message :
ERR : Assembly.GetEntryAssembly() returns null. Set the Application.ResourceAssembly property or use the pack://application:,,,/assemblyname;component/ syntax to specify the assembly to load the resource from.
here is my actual App.xaml with build action setup to page :
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
How to specify the assembly to load the resource from ?
I'm fairly new to WPF and I'm stuck on this problem, thanks in advance.
EDIT 1 :
I tried as my Assembly Name is WpfApplication1 (see here http://postimg.org/image/ksyj9xi5p/)
ResourceDictionary myResourceDictionary = Application.LoadComponent(new Uri("/WpfApplication1;component/Styles/LabelStyle.xaml", UriKind.RelativeOrAbsolute)) as ResourceDictionary;
instead of
ResourceDictionary myResourceDictionary = (ResourceDictionary)reader.LoadAsync(info.Stream);
and get the same error.
Did you try to replace your
Uri uri = new Uri("Styles/LabelStyle.xaml", UriKind.Relative);
by the suggestion that is indicated in you error, that is using the "Pack" syntax ?
pack://application:,,,/assemblyname;component/
Given the information you provided
Uri uri = new Uri("pack://application:,,,/WpfApplication1;component/Styles/LabelStyle.xaml", UriKind.Relative);
This might help you
ResourceDictionary myResourceDictionary = Application.LoadComponent(new Uri("/assemblyname;component/Styles/LabelStyle.xaml", UriKind.RelativeOrAbsolute)) as ResourceDictionary;
You can then find resources within it in the usual manner, e.g., myDictionary["LabelStyle"]
You can set the property: System.Windows.Application.ResourceAssembly as suggested in the error message. Read carefully the documentation. Note that the property can only be set once.

Styles and bindings acting oddly

Right. I've got a small program (that replicates my issue). Basically, it tries to bind to some properties of the object it's styling. It kind of works: it gives me the default value (from the dependency property). I've been thinking this may be because the Style's RelativeSource Self isn't the same as the TextBox it's styling's one. But I don't know. I've tried debugging this, checking time and again that the value set in XAML was actually set. The thing is, with a smaller test program it works. This is just a scale up from that. I don't know what's going wrong.
Thanks!
The code for reproducing this issue:
MainWindow.xaml
<Window x:Class="MyNamespace.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:lcl="clr-namespace:MyNamespace"
Title="My title." Height="350" Width="425" MaxHeight="350" MaxWidth="425" MinHeight="350" MinWidth="425">
<Window.Resources>
<ResourceDictionary Source="TestDictionary.xaml"/>
</Window.Resources>
<Grid>
<TextBox Style="{StaticResource TextBoxWithDefault}" FontSize="36" lcl:MyOptions.Default="Not default." VerticalAlignment="Center"/>
</Grid>
</Window>
MainWindow.xaml.cs
using System.Windows;
namespace MyNamespace
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
public static class MyOptions
{
public static string GetDefault(DependencyObject obj)
{
return (string)obj.GetValue(DefaultProperty);
}
public static void SetDefault(DependencyObject obj, string value)
{
obj.SetValue(DefaultProperty, value);
}
public static readonly DependencyProperty DefaultProperty =
DependencyProperty.RegisterAttached(
"Default",
typeof(string),
typeof(MyOptions),
new PropertyMetadata("Default"));
}
}
TestDictionary.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:lcl="clr-namespace:MyNamespace"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Style TargetType="TextBox" x:Key="TextBoxWithDefault">
<Style.Resources>
<Label Content="{Binding Path=(lcl:MyOptions.Default), Mode=TwoWay, RelativeSource={RelativeSource Self}}"
Foreground="LightGray"
FontSize="{Binding Path=(FontSize), Mode=TwoWay, RelativeSource={RelativeSource Self}}" x:Key="TheLabel"/>
</Style.Resources>
<Style.Triggers>
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">
<Setter Property="Background">
<Setter.Value>
<VisualBrush AlignmentX="Left" AlignmentY="Center" Stretch="None" Visual="{DynamicResource TheLabel}"/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background">
<Setter.Value>
<VisualBrush AlignmentX="Left" AlignmentY="Center" Stretch="None" Visual="{DynamicResource TheLabel}"/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="Background" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
I have no idea what's going wrong here, as a scaled down version of this works perfectly. There's probably something I overlooked, that will seem pretty obvious when I find it. But I can't find it now.
EDIT: Well, it seems I was dumb. The original version (here) uses a Trigger, which means that it gets the parent textbox's value. The question now is: how can I get it working?
Thanks for your time!
The real show-stopper here is that when you use the Label in a VisualBrush, the label isn't part of the TextBox' "Visual Tree" (see for example Sheldon Xiao's answer to this similar question on MSDN: Binding Problem inside VisualBrush).
This means that the label won't inherit the text box' DataContext, and you can't reach the text box from a RelativeSource binding either. In contrast, the accepted answer in your other post sets the actual content of a button, which does make the content part of the button's visual tree.
So I don't think there's a pure XAML solution to this problem - pushing the correct MyOptions.Default from the text box to the label. One possible code-based solution is to scrap the TextBoxWithDefault style and do everything from your attached property when Default changes:
...
public static readonly DependencyProperty DefaultProperty =
DependencyProperty.RegisterAttached(
"Default",
typeof(string),
typeof(MyOptions),
//Listen for changes in "Default":
new PropertyMetadata(null, OnMyDefaultChanged));
private static void OnMyDefaultChanged(DependencyObject sender,
DependencyPropertyChangedEventArgs e)
{
var text = (TextBox)sender;
var myDefault = e.NewValue;
var defaultLabel = new Label();
defaultLabel.Foreground = Brushes.LightGray;
//Explicitly bind the needed value from the TextBox:
defaultLabel.SetBinding(Label.ContentProperty,
new Binding()
{
Source = text,
Path = new PropertyPath(MyOptions.DefaultProperty)
});
text.Background = new VisualBrush()
{
Visual = defaultLabel,
AlignmentX = AlignmentX.Left,
AlignmentY = AlignmentY.Center,
Stretch = Stretch.None
};
text.TextChanged += new TextChangedEventHandler(OnTextWithDefaultChanged);
}
private static void OnTextWithDefaultChanged(object sender,
TextChangedEventArgs e)
{
var text = (TextBox)sender;
var defaultLabel = (text.Background as VisualBrush).Visual as Label;
defaultLabel.Visibility = string.IsNullOrEmpty(text.Text) ?
Visibility.Visible :
Visibility.Collapsed;
}

Categories

Resources