Can I use SizeChange event in XAML? - wpf

I want to change Button drawing based on button size using XAML.
I know it is possible using c# code not sure about XAML
Thanks
Update :
my code is like
<Grid Width="60" Height="60">
<Ellipse Width="57" Height="57" StrockThickness="1">
</Ellipse>
</Grid>
I am applying above style to Button control. but here Width/Height is hard coded. I want it dynamically design time. so when I increase/decrease button size ellipse become accordingly
Thanks again

You should be able to use Property or Event triggers (in XAML). This is probably the preferred way to do this kind of behaviour as it puts the User Experience completely in the designers hands (via XAML) rather than hooking up event handlers (in C# code) that a developer now needs to maintain in order to modify the user experience.
I don't have quick access to VS to test this out right now, but I can try tomorrow if there is no answer by then.

Related

Link Rectangle.Fill to TextBlock.Background

I'm currently migrating from WinForms over to WPF and I'm really struggling with the binding aspects. All i need to do is match the fill property of a rectangle to a textblock.background and keep them in sync. I know I can do this with 'classic' event handlers, but I have 24 textboxes and 24 rectangles, and I'd prefer a more WPF solution. I've toyed with the binding properties but I can't seem to get any type of results since I have no clue with type of binding I even need! Do i need an event, or use a convertor, or possibly a style trigger? Maybe just stick transparent tape on the screen and call it a day?
I know the following doesn't work but this is my level of understanding at this point.
<Rectangle Fill="{Binding Source="textBlock.Background"} />
I've read various articles on databinding but they are all much more advanced, and typically deal with data.
Can someone please shed some light on this helpless n00b!
<TextBlock x:Name="SomeTextBlock" Content="Hi"/>
<Rectangle Fill="{Binding ElementName=SomeTextBlock, Path=Background}"/>
That's the easy way if you are creating them in XAML.

How to use Validation template without the Validation mechanism?

I'm using a control template to show validation errors on each of my controls using the built-in WPF's validation mechanism, and everything works fine. The controlTemplate looks like this:
<ControlTemplate x:Key="MyErrorTemplate" TargetType="{x:Type Control}">
<StackPanel Orientation="Horizontal">
<Border BorderBrush="Red" BorderThickness="2" CornerRadius="3">
<AdornedElementPlaceholder Name="MyAdorner" />
</Border>
<Image Name="imgError"
Source="/MyAssembly;component/Images/ValidationIcon.png"
ToolTip="{Binding ElementName=MyAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"/>
</StackPanel>
</ControlTemplate>
I have read that the validation mechanism wraps the validated control up with the control template (the default one or a custom one like above) whenever the control gets an error.
"When the WPF validation system detects an invalid control it creates
and adorner that holds a control (...), inserts a control into it and sets that control
template to the content of the Validation.ErrorTemplate attached
property.
It positions the adorner above the original control so that the
AdornedElementPlaceholder is exactly above the control and that let us
easily place the control template content relative to the original
control" (see more)
How can I perform this same behavior for another functionality? I mean use "MyErrorTemplate" without the WPF's validation system, is it possible?
so if I understand you correctly you want to have the same validation adorning thing without WPF's validation, right?
The approach then is actually to rebuild the components of WPF's validation system:
create a Dependency Property MyCustomErrorTemplate to hook up your template to the control
create a Dependency Property HasCustomError to enable showing the error
within MyCustomErrorTemplate_Changed hook up to the HasCustomError_Changed to enable showing/hiding of your adorner
create/copy the TemplatedAdorner Class that is then showing your Template
I recommend you use .NET Reflector or ILSpy to look at the following code to get some understanding of what's going on. This isn't actually very complex or hard to understand:
in PresentationFramework.dll:
System.Windows.Controls.Validation (especially the private static void ShowValidationAdornerHelper(DependencyObject targetElement, DependencyObject adornerSite, bool show, bool tryAgain)
MS.Internal.Controls.TemplatedAdorner (sadly this is internal, so you either have to copy it or use some Reflection on it)
Why not? You can have similar attached properties MyValidation.Errors and HasErrors and fill them with your custom logic. And you can have trigger that replaces ControlTemplate with ErrorTemplate when HasError is true. I think this simple approach will do that you need although i am not quite sure that i exactly understand that you need.

WPF Windows to Tabs

I have an already made WPF application which is Windowed based and now I wish to implement tabbed controls instead of each of those separate windows. What would be the easiest and fastest way to reuse?
Thanks
Typically when I want to convert, I take the contents of each Window (which is usually wrapped in a Grid) and I convert them to a UserControl. You can basically move the entire Xaml and code-behind almost as-is, with only minor tweaks.
You then replace your Window contents with the UserControl, and you can reuse the same UserControl in a tab, or anywhere else.
Or you could convert you Windows to Pages and create frames in the tabs and put the page in the frame. It might be easier convert you Windows to Pages (and it might not) - depends on your Windows. I like the UserControl answer. Just putting another possilble option out there.
<TabItem>
<TabItem.Header>
<TextBlock Style="{StaticResource TabItemHeader}">DocTxt</TextBlock>
</TabItem.Header>
<Frame Source="PageViewDocText.xaml" BorderThickness="0" Margin="0"/>
</TabItem>
Transfort all your windows into UserControl and build your new window with your TabControl.

MVVM Command without A Button

I want to initiate a bound command, but I don't want to use a Button on my UserControl. In effect the UserControl is itself a Button. When it is clicked anywhere on its surface I want to initiate a bound command. Is there a way to give a UserControl a command?
In a side note: one command for one control and only a few certain out-of-the-box controls? This all seems a little clunky. I'm starting to think that MVVM is impractical. I can decouple my UI just fine with Interfaces and OOP. Anyway, I still have hope.
Also, I'm not willing to hack anything or use an expensive workaround. If I can't do this, I'm abandoning MVVM.
Take a look at the ICommandSource interface here: http://msdn.microsoft.com/en-us/library/system.windows.input.icommandsource.aspx. If you want a control to have a command, then your control should implement this interface. Examples of controls that implement this interface are ButtonBase and MenuItem. Hope this helps.
If your UserControl is essentially a Button, why are you writing your own UserControl instead of using the Button class?
To add more info, here's what you do:
Subclass Button, put any extra DependencyProperties that you need in there - it should be a very empty class (you could even have something like public class MyCoolButton : Button { }
Add a Style whose TargetType is MyCoolButton - don't name the style so it applies to all MyCoolButtons
Override the default Template of the style, then paste in your Xaml code. You might have to do some work here to handle the "Normal / Pushed / Disabled" states. If you're using v4.0, you can use VSM here.
I will agree with Paul Betts.
Quite often I create my own ListBoxItemContainerStyle using a button as the top container with nothing but a propertyless content presenter in it. This allows me to use the buttons functionality (like Command) without having the Windows chrome on it.
Putting it in the ListBoxItemContainerStyle also lets me make it so that when it is clicked it does not display the normal dotted border (FocusVisualStyle={x:Null}).
Are you using Visual Studio or Expression Blend to do your styling?
Additionally, some MVVM frameworks provide an interface for adding a command-ish ability to controls other than buttons. Caliburn has a pretty rich command pattern. I am not sure if it allows binding commands on non-button controls, however.
The OP asked for an example of how you could use a button control, but with the content properly filling the entire button. You can do this using the ContentAlignment properties:
<Button HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<Button.Content>
<Grid IsHitTestVisible="False">
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Row0" />
<TextBlock Grid.Row="1" Text="Row1" />
</Grid>
</Button.Content>
</Button>
This creates a button with two labels spaced using a Grid control. I mark the Grid to turn off HitTestVisible, as you have to decide which controls should interact like the button and which should interact like controls. For instance, you might have an embedded TextBox that you want to be clickable without clicking the button, in which case it should have HitTestVisible=True.
WPF supports layers and transparency :
Panel.ZIndex
You can create anything that supports commanding on a superior transparent layer, the size you want, to act as a button.

WPF Binding Help

I haven't used WPF that much so the solution to this is probably pretty easy.
In the ide I'm developing it will have multiple controls(text editor) each being hosted in a tab, much like VS does for each source file. When the user clicks new the "host" creates a new EditorWindow(a usercontrol), creates a new tab, and tells the tab to display the EditorWindow it created, and then updates a property called currentWindow (of type EditorWindow) with the one that's currently active. Inside the EditorWindow is the text editor whose name is textEditor(also a property). What I'm trying to do is take this code from the quick start source of the text editor control I'm using
<StackPanel>
<CheckBox Checked="EditiorOptionsChecked" IsChecked="{Binding ElementName=Control, Path=currentWindow.textEditor.IsIndicatorMarginVisible}" Content="Indicator margin visible" />
<CheckBox Checked="EditiorOptionsChecked" IsChecked="{Binding ElementName=Control, Path=currentWindow.textEditor.IsLineNumberMarginVisible}" Content="Line number margin visible" />
<CheckBox Checked="EditiorOptionsChecked" IsChecked="{Binding ElementName=Control, Path=currentWindow.textEditor.IsRulerMarginVisible}" Content="Ruler margin visible (useful for fixed-width fonts only)" />
<CheckBox Checked="EditiorOptionsChecked" IsChecked="{Binding ElementName=Control, Path=currentWindow.textEditor.IsSelectionMarginVisible}" Content="Selection margin visible" />
</StackPanel>
put that in the host controls xaml, and bind the checkboxes to the syntax editor. I've tried a couple different things to no avail. Control is the name of the window hosting all the tabs, and path is obviously supposed to be the property that the checkboxes are bound too. I'm pretty sure the problem is that at initial run-time currentWindow isn't initialized so therefore my bindings aren't ever getting updated, but I'm at a loss as to how to fix this issue. Thanks!
Since you are new to WPF, you may not know that properties have to implement some sort of change notifications in order for bindings to work. For instance, if any of the properties in the the path "currentWindow.textEditor.IsIndicatorMarginVisible" change, you need to inform the binding engine that it has changed. If you implement these properties as DependencyPropertys, the change tracking comes for free. Otherwise, you should implement INotifyPropertyChanged.
I've found that the Snoop utility is the easiest way to do quick binding debugging, you should try using it and see if it tells you anything useful on the bound properties.

Resources