Dialog form in wpf change content - wpf

I want to display a dialog form for new and edit actions... However title, buttons , and few other things should change.
I am wondering how i could implement this. Provide an enum value at constructor ? Like Mode.New or Mode.Edit ? Is there a way to avoid writing code like spNewButtons.Visibillity=Collapsed .. etc , and put it inside wpf ?

You can bind visibility with your mode property, and create a specific IValueConverter to convert the mode to a proper Visibility value. ie:
<StakPanel Visibility={Binding Mode,Converter={StaticResource myProperConverter}}></StackPanel>

Usually my WPF dialogs are all ContentControls that get displayed in a Popup.
My code usually looks like this:
<Grid Name="RootPanel">
<!-- Other Content -->
<!-- Popup is always last so it gets displayed on top of other contnet -->
<local:PopupPanel
local:PopupPanel.PopupParent="{Binding ElementName=RootPanel}"
local:PopupPanel.IsPopupVisible="{Binding IsPopupVisible}"
local:PopupPanel.PopupEnterKeyCommand="{Binding SaveCommand}"
local:PopupPanel.PopupEscapeKeyCommand="{Binding CancelCommand}">
<DockPanel>
<!-- Header -->
<Label DockPanel.Dock="Top" Content="{Binding PopupHeader}" />
<!-- Buttons -->
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="Save" Command="{Binding PopupSaveCommand}" />
<Button Content="Cancel" Command="{Binding PopupCancelCommand}" />
</StackPanel>
<!-- Actual content displayed is determined by DataTemplates -->
<ContentControl Content="{Binding PopupContent}" />
</DockPanel>
</local:PopupPanel>
</Grid>
I removed a lot of the styles to make this easier to read, but you can see the general idea of how it's put together. My ViewModel usually contains properties for IsPopupVisible, PopupContent, and PopupHeader, and commands for PopupSaveCommand and PopupCancelCommand
I use my own custom popup in most cases, although the same thing could be done with a WPF popup.

Related

Expander-like WPF control that only hides empty children

In my WPF view, I need something similar to an Expander or a TreeView, but instead of completely hiding the content, I only want to hide empty parts, i.e. TextBoxes with null or empty text, or empty ItemCollections.
I thought about using a style with a DataTrigger or set Visibility with a converter, but how would I link that to the parent's setting (e.g. IsExpanded)?
I would like to avoid doing this in the ViewModel, as that would need a property for each section (and I need lots of them), but it's purely visual and therefore IMHO it only belongs to the View.
So I guess the way to go is to use DependencyProperties or write some CustomControls, but I don't have an idea where to start. The XAML of the end result could look something like this:
<CustomExpander Header="Main" CollapseContentIfEmpty="True">
<CustomExpander Header="Section1" CollapseContentIfEmpty="True">
<StackPanel>
<TextBox Text="{Binding SomeString}" />
<TextBox Text="{Binding SomeEmptyString}" />
</StackPanel>
</CustomExpander>
<CustomExpander Header="Section2" CollapseContentIfEmpty="True">
<ListView ItemsSource="{Binding SomeCollectionView}" />
</CustomExpander>
</CustomExpander>
In this example, if CollapseContentIfEmpty is set to true and the CollectionView shows no elements (e.g. due to filters), only the content of SomeString should be visible, along with all the headers. If SomeString is empty, only "Main" should be visible, as now all child CustomExpanders are empty as well.
Setting CollapseContentIfEmpty to false (e.g. via a Button like in Expander) would show all Children again, regardless if they are empty or not.
I thought about using a style with a DataTrigger or set Visibility with a converter, but how would I link that to the parent's setting (e.g. IsExpanded)?
Use a binding with a {RelativeSource}.
In the following example, the TextBlock is invisible unless you set the Tag property of the parent UserControl to true:
<UserControl xmlns:sys="clr-namespace:System;assembly=mscorlib">
<UserControl.Tag>
<sys:Boolean>false</sys:Boolean>
</UserControl.Tag>
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</UserControl.Resources>
<StackPanel>
<TextBlock Text="text..."
Visibility="{Binding Tag,
RelativeSource={RelativeSource AncestorType=UserControl},
Converter={StaticResource BooleanToVisibilityConverter}}" />
</StackPanel>
</UserControl>
You can of course replace the UserControl with a custom control with a custom bool property.
An Expander collapses its entire Content which is different from hiding specific controls in that content.

WPFToolkit:Split button dropdown button disable button

I am using WPF split button which is inherited from
xmlns:extToolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit/extended"
The issue is I want to disable , the button ' the one below(Right side of Button 'Conf' in below 'downarrow present in the below fig) , If user clicks on Left side of the button the rightside should be disabled and the button(leftside) background should change to yellow.please find below the xaml , I am using the wpf split button , dropdown content in this case .please let me know if you have any idea
<extToolkit:SplitButton x:Name="ABCbutton"
VerticalAlignment="Center"
Command="{Binding ACommand}"
FontSize="16>
<TextBlock HorizontalAlignment="Center"
IsEnabled="{Binding IsEnabled, ElementName=AButton}"
Text="A"/>
<extToolkit:SplitButton.DropDownContent>
<StackPanel>
<Button Command="{Binding BCommand}"
Padding="3"
Style="{DynamicResource
DropDownButtonMenuButton}">
<TextBlock Margin="0,3,6,3"
Text="B"/>
</Button>
<Button Command="{Binding BCommand}"
Padding="3"
Style="{DynamicResource
DropDownButtonMenuButton}">
<TextBlock Margin="0,3,6,3"
HorizontalAlignment="Stretch"
Text="C"/>
</Button>
</StackPanel>
</extToolkit:SplitButton.DropDownContent>
</extToolkit:SplitButton>
In a case like this, you will likely be better off creating your own control. The split button can't really handle what you are talking about without a good deal of modification.
Essentially your new control will consist of two buttons, visually styled so that they look like they blend together. Each will have it's own background and enabled property. Add a ViewModel to help control behaviors and set properties, and I think you would be in business. Keep in mind that all of the controls that are supplied in any of the toolkits, frameworks, control packs, etc are made with the primitive types of drawing and framework elements (line, rectangle, border, content presenter, panel, etc) with specialized behavior code.
I end up making a lot of custom controls just because there is not one that perfectly replicates what I want.

Modify content of DataTemplate in code for a Grid control

I have the following Xaml for a grid and I want to be able to modify the value of the Content in code. I want to depending on the condition, not display the "[+]". How do I do that. Also how do i trigger an event to make the change. I am using an Infragistic XamGrid but I think it will apply to other grids too.
<ig:UnboundColumn Key="Sel" x:Name="ubcSel" IsFixed="Left" Width="44" HeaderText=" " PropertyChanged="UnboundColumn_PropertyChanged">
<ig:UnboundColumn.ItemTemplate>
<DataTemplate>
<HyperlinkButton Name="hblSel" Click="hblSel_Click"
Content="[+]" FontWeight="Bold" FontSize="12" HorizontalAlignment="Center" />
</DataTemplate>
</ig:UnboundColumn.ItemTemplate>
</ig:UnboundColumn>
Why don't you use binding on the content property and place the conditional logic in an exposed ViewModel property?

Adding and changing usercontrol at run time in a WPF application

I have a situation as follows, i am going to use WPF for first time, so any suggestion abt how to proceed whould be great:
I hav a drop down, when i select any item from it - it should change the structure of controls in same window. New controls contain - two menu items and a text box and a list box. Selecting one menuitem will display text box and other will show list box. Now for each item in initial combo box i will have different info for the each menu items.
Problems:
Say i have 10 items in combo box - and 2 menu items for each - so 20 different stuff to show.
-- How should i declare these 20 different stuffs
-- How should i load each when a particular combination is selected
You should look at ControlTemplate. You can define a set of templates, then apply them to a control causing them to be whatever you want them to be. so, when the item changed event fires on your dropdown, load and apply the template that you want.
<!--- your xaml file --->
<Control x:Name="Main"/>
// you CS file....
OnItemChanage(....)
{
if ( Main!= null )
Main.Template = MyNewTemplate;
}
If you want to show multiple sets of controls at once, dd all of the controls to your window and set their Visibility using a data binding, and use the ComboBox to update the propertie the controls are bound to.
Or if you only want to show one control at a time, just use a DataContext from the ComboBox:
<Window.DataContext>
<x:Array x:Key="myItems">
<local:Item MenuItem1="abc" MenuItem2="def" />
<local:Item MenuItem1="ghi" MenuItem2="jkl" />
...
<local:Item MenuItem1="ghi" MenuItem2="jkl" />
</x:Array>
</Window.DataContext>
<Grid>
...
<ComboBox x:Name="selection" ItemsSource="{Binding}">
...
<StackPanel DataContext="{Binding /}" ...>
<MenuItem Header="{Binding MenuItem1}" OnClick="DisplayListBox" />
<MenuItem Header="{Binding MenuItem2}" OnClick="DisplayTextBox" />
<TextBox Visibility="Hidden" ... />
<ListBox Visibility="Hidden" ... />
</StackPanel>
</Grid>
with appropriate code for DisplayListBox and DisplayTextBox

How do I make modal dialog for a Page in my WPF-application?

I have a WPF Window which has a among other controls hosts a Frame. In that frame I display different pages. Is there way to make a dialog modal to only a page? When I'm showing the dialog it should not be possible to click on any control on the page but it should be possible to click on a control on the same window that is not on the page.
If I am correct in interpreting your message, you want something that works similar to what
Billy Hollis demonstrates in his StaffLynx application.
I recently built a similar control and it turns out that this sort of idea is relatively simple to implement in WPF. I created a custom control called DialogPresenter. In the control template for the custom control, I added markup similar to the following:
<ControlTemplate TargetType="{x:Type local=DialogPresenter}">
<Grid>
<ContentControl>
<ContentPresenter />
</ContentControl>
<!-- The Rectangle is what simulates the modality -->
<Rectangle x:Name="Overlay" Visibility="Collapsed" Opacity="0.4" Fill="LightGrey" />
<Grid x:Name="Dialog" Visibility="Collapsed">
<!-- The template for the dialog goes here (borders and such...) -->
<ContentPresenter x:Name="PART_DialogView" />
</Grid>
</Grid>
<ControlTemplate.Triggers>
<!-- Triggers to change the visibility of the PART_DialogView and Overlay -->
</ControlTemplate.Triggers>
</ControlTemplate>
I also added a Show(Control view) method, which finds the the 'PART_DialogView', and adds the passed in view to the Content property.
This then allows me to use the DialogPresenter as follows:
<controls:DialogPresenter x:Name="DialogPresenter">
<!-- Normal parent view content here -->
<TextBlock>Hello World</TextBlock>
<Button>Click Me!</Button>
</controls:DialogPresenter>
To the buttons event handler (or bound command), I simply call the Show() method of the DialogPresenter.
You can also easily add ScaleTransform markup to the DialogPresenter template to get scaling effects shown in the video. This solution has neat and tidy custom control code, and a very simple interface for your UI programming team.
Hope this helps!
I have a project on github which is a custom FrameworkElement that allows you to display modal content over the primary content.
The control can be used like this:
<c:ModalContentPresenter IsModal="{Binding DialogIsVisible}">
<TabControl Margin="5">
<Button Margin="55"
Padding="10"
Command="{Binding ShowModalContentCommand}">
This is the primary Content
</Button>
</TabItem>
</TabControl>
<c:ModalContentPresenter.ModalContent>
<Button Margin="75"
Padding="50"
Command="{Binding HideModalContentCommand}">
This is the modal content
</Button>
</c:ModalContentPresenter.ModalContent>
</c:ModalContentPresenter>
Features:
Displays arbitrary content.
Does not disable the primary content whilst the modal content is being displayed.
Disables mouse and keyboard access to the primary content whilst the modal content is displayed.
Is only modal to the content it is covering, not the entire application.
can be used in an MVVM friendly way by binding to the IsModal property.
Why not just use nested message pumps to create modal controls
http://deanchalk.com/wpf-modal-controls-via-dispatcherframe-nested-message-pumps/
You are not looking for a modal dialog here. You need a function that will disable the "page" control, show a dialog, and re-enable it when the dialog closes.
I'm not too sure whether you understand what a modal dialog is meant to do though?

Resources