WPF Prism Dialog Service WindowStartupLocation not recalculating position - wpf

I'm using Prism in a WPF project. I implemented a Dialog Service, as suggested in the Prism web site (here)
I have a MainWindow in charge of calling the "_dialogService.ShowDialog(...)" method on request.
Everything seems to work fine, except one thing (unfortunately!):
The program runs in a resizable window (not full screen) with a defined size, let's say 1600x900 but it doesn't matter.
If I resize the window (i.e. to increase the size), next time I open the dialog , it's no more centered.
It keeps the "centered position" of the initial window size, but it doesn't recalculate it after the window resize.
Can anybody help me to find a way to fix this behaviour?
Here's the code used in the UserControl:
<prism:Dialog.WindowStyle>
<Style TargetType="Window">
<Setter Property="prism:Dialog.WindowStartupLocation" Value="CenterScreen" />
<Setter Property="ResizeMode" Value="NoResize"/>
<Setter Property="ShowInTaskbar" Value="False"/>
<Setter Property="SizeToContent" Value="WidthAndHeight"/>
<Setter Property="BorderThickness" Value="0" />
<Setter Property="WindowStyle" Value="None" />
</Style>
</prism:Dialog.WindowStyle>
And here's the parts in the MainWindowViewModel.cs
public MainWindowViewModel(IRegionManager regionManager, IEventAggregator ea, IDialogService dialogService)
{
_regionManager = regionManager;
_ea = ea;
_dialogService = dialogService;
}
private void ShowDialog(DialogData data)
{
_dialogService.ShowDialog("DlgConfirmDialog", new DialogParameters($"title={data.Title}&message={data.Message}), r =>
{
//do something
});
}

Related

ControlTemplate Trigger don't work in designer (runtime ok)

I have a custom Control derived from Window:
class LVSDialog : Window
with DependencyProperty ShowCloseButton
and a Style with ControlTemplate and Trigger:
<Style TargetType="{x:Type loc:LVSDialog}" x:Key="LVSDialogStyle">
...
<Setter Property="Template">
...
<Button x:Name="closeButton" />
...
<ControlTemplate.Triggers>
<Trigger Property="loc:LVSDialog.ShowCloseButton" Value="False">
<Setter TargetName="closeButton" Property="Visibility" Value="Collapsed" />
</Trigger>
</ControlTemplate.Triggers>
</Setter>
Everything works fine in the runtime, but in Designer it doesn't take sence if I change this Property - Button is visible all the time:
<loc:LVSDialog ...
ShowCloseButton="False" Style="{StaticResource LVSDialogStyle}">
I have searched for a solution in google and here - all questions are about runtime functionality, designer problems are either unanswered or not working suggestions.
Is it possible at all use full functions in design time?
P.S. My VisualStudio is 2012. Framework 4.0
If you change the base class to Control instead of Window it will work:
public class LVSDialog : Control
{
public bool ShowCloseButton
{
get { return (bool)GetValue(ShowCloseButtonProperty); }
set { SetValue(ShowCloseButtonProperty, value); }
}
// Using a DependencyProperty as the backing store for ShowCloseButton. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ShowCloseButtonProperty =
DependencyProperty.Register("ShowCloseButton", typeof(bool), typeof(LVSDialog), new PropertyMetadata(true));
}
From Topicstarter:
I have changed to Control, added internal window, set it content to my control and added Show() and ShowDialog() methods:
private Window parentWindow;
...
public void Show()
{
if (parentWindow == null)
{
parentWindow = new Window {Content = this, WindowStyle = ...};
}
parentWindow.Show();
}
Everything works fine, designer shows all properties "live".

How to set a DepedencyProperty by a style setter?

My user control have the following DP:
public static readonly DependencyProperty ButtonAnimationColorProperty =
DependencyProperty.Register("ButtonAnimationColor", typeof(Color), typeof(MyControl),
new FrameworkPropertyMetadata(Colors.RoyalBlue, FrameworkPropertyMetadataOptions.AffectsRender, ThemeUpdate));
public Color ButtonAnimationColor
{
get { return (Color)GetValue(ButtonAnimationColorProperty ); }
set { SetValue(ButtonAnimationColorProperty , value); }
}
This control is compiled into a dll, that I use in others solutions. It works perfect well when I set directly:
<ns:MyControl ButtonAnimationColor="Green" />
The problem occurs when I try to set this DP by using a Style Setter, like that:
<ns:MyControl>
<ns:MyControl.Style>
<Style>
<Setter Property="ButtonAnimationColor" Value="Green" />
</Style>
</ns:MyControl.Style>
</ns:MyControl>
It give me the following error:
The member "ButtoAnimationColor" is not recognized or is not acessible.
What changes I need to make in my code to be able to set the property like that?
Try setting the target type for the style:
<ns:MyControl.Style>
<Style TargetType="{x:Type ns:MyControl}">
<Setter Property="ButtonAnimationColor" Value="Green" />
</Style>
</ns:MyControl.Style>

How to change ContentControl's Content property using DataTemplate's DataTriggers based on Window's ViewModel property which is an enum value

I ask for your help in solving something that is simply said and most likely simply done but not for me at the moment.
What I'm developing is an application that looks like Office 2013 using FluidUI control set.
I want to achieve view switcher from Word/Access where on ribbon there is Views tab and there are buttons which switches views.
I thought that storing whole View object inside my ViewModel's property CurrentView is wrong way and I try to make this application as MVVM pure as possible. This application is more like "How to write app using MVVM" because I'm still learing WPF.
Ok. So I have my Window (MainWindowModern to be correct) which has Fluid Ribbon. There are 3 buttons to switch views (I call them Editors).
What they do is to change MainWindowModern's ViewModel's CurrentView property and set new enum value to it. This part of setting new enum value is done and works.
Now. The main body of the window is just ContentControl. Now I want to change this ContentControl's Content property based on DataContext.CurrentView property value. Like I said it before. I don't want to do any code-behind inside view's c# (i'm writing this app in C#) file.
The only thing that doesn't work is just changing ContentControl Content property. I'm trying to do this using DataTemplates and DataTemplate.Triggers
Now here's what I've got so far (without unrelated code).
The Window's XAML
<Fluent:MetroWindow
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Fluent="clr-namespace:Fluent;assembly=Fluent"
xmlns:localVM="clr-namespace:MVVMTest.ViewModels"
xmlns:local="clr-namespace:MVVMTest"
x:Class="MVVMTest.Views.MainWindowModern"
x:Name="ThisWindow"
Title="Dialogue Editor (Modern UI Version)"
Width="1280" Height="480"
RibbonThemeColor="Red" WindowState="Maximized"
Icon="..\Assets\App\AppIcon_32x32.png">
<Window.Resources>
<DataTemplate x:Key="CharactersEditorTemplate">
<TextBlock Text="Characters Editor Template Body" />
</DataTemplate>
<DataTemplate x:Key="ChaptersEditorTemplate">
<TextBlock Text="Chapters Editor Template Body" />
</DataTemplate>
<DataTemplate x:Key="ConversationsEditorTemplate">
<TextBlock Text="Conversations Editor Template Body" />
</DataTemplate>
<DataTemplate x:Key="aaa" DataType="{x:Type ContentControl}" >
<TextBlock Text="{Binding ElementName=ThisWindow, Path=DataContext.CurrentView}" />
<DataTemplate.Triggers>
<!--<DataTrigger Binding="{Binding CurrentView}">
<DataTrigger.Value>
<localVM:EditorView>CharactersEditor</localVM:EditorView>
</DataTrigger.Value>
<Setter Property="Content" Value="{StaticResource CharactersEditorTemplate}" />
</DataTrigger>
<DataTrigger Binding="{Binding CurrentView}">
<DataTrigger.Value>
<localVM:EditorView>ChaptersEditor</localVM:EditorView>
</DataTrigger.Value>
<Setter Property="Content" Value="{StaticResource ChaptersEditorTemplate}" />
</DataTrigger>
<DataTrigger Binding="{Binding CurrentView}">
<DataTrigger.Value>
<localVM:EditorView>ConversationsEditor</localVM:EditorView>
</DataTrigger.Value>
<Setter Property="Content" Value="{StaticResource ConversationsEditorTemplate}" />
</DataTrigger>-->
<DataTrigger Binding="{Binding ElementName=ThisWindow, Path=DataContext.CurrentView}">
<DataTrigger.Value>
<localVM:EditorView>ChaptersEditor</localVM:EditorView>
</DataTrigger.Value>
<DataTrigger.Setters>
<Setter Property="Content" Value="{StaticResource ChaptersEditorTemplate}" />
</DataTrigger.Setters>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Window.Resources>
<Window.DataContext>
<localVM:MainWindowVM />
</Window.DataContext>
<DockPanel x:Name="LayoutRoot" LastChildFill="True">
<Fluent:Ribbon DockPanel.Dock="Top">
<Fluent:RibbonTabItem Header="VIEW" Fluent:KeyTip.Keys="V" ReduceOrder="ViewsRibbonGroupBox, ViewsRibbonGroupBox, ViewsRibbonGroupBox">
<Fluent:RibbonGroupBox Name="ViewsRibbonGroupBox" Header="Views">
<Fluent:Button Name="CharactersViewButton"
Header="Characters"
LargeIcon="..\Assets\Ribbon\View\CharacterEditorIcon_32x32.png"
Icon="..\Assets\Ribbon\View\CharacterEditorIcon_32x32.png"
Command="{Binding SwitchToCharactersEditorCommand}" >
<Fluent:Button.ToolTip>
<Fluent:ScreenTip
Image="..\Assets\Ribbon\View\CharacterEditorIcon_32x32.png"
Title="Characters Editor"
Text="Changes current view to Characters Editor view.
In this view user can:
• List existing characters
• Create new characters
• Edit existing characters
• Delete existing characters
It is also possible to manage character's emotions in this view." />
</Fluent:Button.ToolTip>
</Fluent:Button>
<Fluent:Button Name="ChaptersViewButton"
Header="Chapters"
LargeIcon="..\Assets\Ribbon\View\ChapterEditorIcon_32x32.png"
Icon="..\Assets\Ribbon\View\ChapterEditorIcon_32x32.png"
Command="{Binding SwitchToChaptersEditorCommand}" >
<Fluent:Button.ToolTip>
<Fluent:ScreenTip
Image="..\Assets\Ribbon\View\ChapterEditorIcon_32x32.png"
Title="Chapters Editor"
Text="Changes current view to Chapters Editor view.
In this view user can:
• List existing chapters
• Create new chapters
• Edit existing chapters
• Delete existing chapters
It is also possible to manage chapters's missions in this view." />
</Fluent:Button.ToolTip>
</Fluent:Button>
<Fluent:Button Name="ConversationsViewButton"
Header="Conversations"
LargeIcon="..\Assets\Ribbon\View\ConversationEditorIcon_32x32.png"
Icon="..\Assets\Ribbon\View\ConversationEditorIcon_32x32.png"
Command="{Binding SwitchToConversationsEditorCommand}" >
<Fluent:Button.ToolTip>
<Fluent:ScreenTip
Image="..\Assets\Ribbon\View\ConversationEditorIcon_32x32.png"
Title="Conversations Editor"
Text="Changes current view to Conversations Editor view.
In this view user can:
• List existing conversations
• Create new conversations
• Edit existing conversations
• Delete existing conversations
It is also possible to manage conversations's statements and statement's stages in this view."
DisableReason="Please define at least one chapter with at least one mission in it to enable Conversations Editor.
Also it would be helpful to define at least one character with at least one emotion.
It is optional action but highly recommended." />
</Fluent:Button.ToolTip>
</Fluent:Button>
</Fluent:RibbonGroupBox>
</Fluent:RibbonTabItem>
</Fluent:Ribbon>
<ContentControl Name="MainContent" ContentTemplate="{StaticResource aaa}" />
</DockPanel>
</Fluent:MetroWindow>
Window's ViewModel and the enum
using MVVMTest.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MVVMTest.ViewModels {
public enum EditorView {
CharactersEditor,
ChaptersEditor,
ConversationsEditor
}
public class MainWindowVM : ViewModelBase {
public MainWindowVM() {
this.init();
}
protected void init() {
this.Characters = new ObservableCollection<CharacterVM>();
this.initCommands();
this.initSampleData();
}
protected void initSampleData() {
Character ch1 = new Character() { Name = "Character 1" };
Emotion e1 = new Emotion() { Name = "Emotion 1" };
ch1.Emotions.Add(e1);
CharacterVM ch1vm = new CharacterVM(ch1);
this.Characters.Add(ch1vm);
this.CurrentView = EditorView.ConversationsEditor;
}
protected void initCommands() {
this.SwitchToCharactersEditorCommand = new RelayCommand(param => this.SwitchToCharactersEditor(), param => this.CanSwitchToCharactersEditor());
this.SwitchToChaptersEditorCommand = new RelayCommand(param => this.SwitchToChaptersEditor(), param => this.CanSwitchToChaptersEditor());
this.SwitchToConversationsEditorCommand = new RelayCommand(param => this.SwitchToConversationsEditor(), param => this.CanSwitchToConversationsEditor());
}
public ObservableCollection<CharacterVM> Characters { get; set; }
protected EditorView _currentView;
public EditorView CurrentView {
get { return this._currentView; }
set {
if (this._currentView == value) {
return;
}
this._currentView = value;
this.OnPropertyChanged("CurrentView");
}
}
#region Commands
#region View Tab
#region Switch To Characters Editor
public RelayCommand SwitchToCharactersEditorCommand { get; private set; }
protected void SwitchToCharactersEditor() {
this.CurrentView = EditorView.CharactersEditor;
}
protected bool CanSwitchToCharactersEditor() {
if (this.CurrentView != EditorView.CharactersEditor) {
return true;
}
return false;
}
#endregion Switch To Characters Editor
#region Switch To Chapters Editor
public RelayCommand SwitchToChaptersEditorCommand { get; private set; }
protected void SwitchToChaptersEditor() {
this.CurrentView = EditorView.ChaptersEditor;
}
protected bool CanSwitchToChaptersEditor() {
if (this.CurrentView != EditorView.ChaptersEditor) {
return true;
}
return false;
}
#endregion Switch To Chapters Editor
#region Switch To Conversations Editor
public RelayCommand SwitchToConversationsEditorCommand { get; private set; }
protected void SwitchToConversationsEditor() {
this.CurrentView = EditorView.ConversationsEditor;
}
protected bool CanSwitchToConversationsEditor() {
if (this.CurrentView != EditorView.ConversationsEditor) {
return true;
}
return false;
}
#endregion Switch To Conversations Editor
#endregion View Tab
#endregion Commands
}
}
When this is all done the next step is to add animation to view switch just like on ModernUI Apps (or android smartphones) so the old content goes over the border of the window and new content comes from the other side. If it is not possible then I'll stop with just working switcher.
The good news is that this is actually pretty easy to do, including the animation switching. What you need is an ItemsControl to host your subviews. The ItemsControl allows you to use a DataTemplateSelector. So based on your enum value you can produce some output that the selector can use to determine which datatemplate to use. Try some research on the selector. If your are still confused feel free to reach out to me. Good luck.
For animations, I suggest a container control that would host your subviews. Check out this link for a pretty solid implementation to get you started.

How can I prevent row selection in the WPF Toolkit DataGrid?

I see a few options available for row selection, but 'No Selection' is not one of them. I've tried handling the SelectionChanged event by setting SelectedItem to null, but the row still seems selected.
If there is no easy support for preventing this, would it be easy to just style the selected row the same as an unselected one? That way it could be selected, but the user has no visual indicator.
You have to call DataGrid.UnselectAll asynchronously with BeginInvoke to get it to work. I wrote the following attached property to handle this:
using System;
using System.Windows;
using System.Windows.Threading;
using Microsoft.Windows.Controls;
namespace DataGridNoSelect
{
public static class DataGridAttach
{
public static readonly DependencyProperty IsSelectionEnabledProperty = DependencyProperty.RegisterAttached(
"IsSelectionEnabled", typeof(bool), typeof(DataGridAttach),
new FrameworkPropertyMetadata(true, IsSelectionEnabledChanged));
private static void IsSelectionEnabledChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var grid = (DataGrid) sender;
if ((bool) e.NewValue)
grid.SelectionChanged -= GridSelectionChanged;
else
grid.SelectionChanged += GridSelectionChanged;
}
static void GridSelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
var grid = (DataGrid) sender;
grid.Dispatcher.BeginInvoke(
new Action(() =>
{
grid.SelectionChanged -= GridSelectionChanged;
grid.UnselectAll();
grid.SelectionChanged += GridSelectionChanged;
}),
DispatcherPriority.Normal, null);
}
public static void SetIsSelectionEnabled(DataGrid element, bool value)
{
element.SetValue(IsSelectionEnabledProperty, value);
}
public static bool GetIsSelectionEnabled(DataGrid element)
{
return (bool)element.GetValue(IsSelectionEnabledProperty);
}
}
}
I sourced this blog post in creating my solution.
Please apply below style to datagid cell to solve the problem:
<Style x:Key="MyDatagridCellStyle" TargetType="{x:Type Custom:DataGridCell}">
<Setter Property="Focusable" Value="false"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="#434342"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="FontSize" Value="11"/>
<Setter Property="FontWeight" Value="Normal"/>
</Style>
Any row selection can be avoided using property 'IsHitTestVisible' as False. But It will not allow you to use scrollbar of your datagrid. Datagrid will be locked in this case.
Another solution is:
You can apply style to cell of datagrid. It worked for me. Please use code as below:
Above code worked for me. Hope it will work for you too.
Regards,
Vaishali

Autocompletebox text in Silverlight

I'm having trouble getting the autocomplete box in System.Windows.Controls.Input working as I wish. When I start typing the dropdown section that displays the filtered list doesn't show the property that I'm binding to, it shows the class name instead.
So in the example below, when I type in my - instead of showing 'My Name' it shows MyNamespace.Person. However, when I select the item from the autocomplete list, it displays the FullName property in the textbox. I'm sure I'm just missing a simple autocomplete box property somewhere but I can't see it.
Example code:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName
{
get { return string.Format("{0} {1}", FirstName, LastName); }
}
}
In my xaml code behind I create some Person objects and store them in a list and bind that list to an autocomplete box
List<Person> people = new List<Person>();
people.Add(new Person { FirstName = "My", LastName = "Name" });
people.Add(new Person { FirstName = "Fernando", LastName = "Torres" });
acbNames.ItemsSource = people;
My xaml:
<my:AutoCompleteBox Name="acbNames" ValueMemberPath="FullName" />
/* after entering 'my', auto complete displays 'MyNamespace.Person' instead of 'My Name', but displays 'My Name' after selecting the item from the list */
It turns out I need to use an ItemTemplate for the dropdown part of the AutoCompleteBox, so the xaml for it would now be as follows:
<my:AutoCompleteBox Name="acbNames" ValueMemberBinding="{Binding FullName}">
<my:AutoCompleteBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding FullName}"/>
</DataTemplate>
</my:AutoCompleteBox.ItemTemplate>
</my:AutoCompleteBox>
Yes, your problem was because you didn't put item template.
But if you put item template and still got problem read what Sandro has wroted.
I had same problem. I solved it using a Static resource for the Control Style
This is the style i used:
<Style x:Key="autocomplete" TargetType="sdk1:AutoCompleteBox">
<Setter Property="Margin" Value="5,0,5,0"/>
<Setter Property="MinWidth" Value="100"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property ="HorizontalAlignment" Value="Right"/>
</Style>
If I don't use this style my Customs Item are not displayed correctly as I configure in DataItem, instead it show the Class name.
share|edit
This works for me too but only when i applied some custom theme style from toolkit.
There are some other workarounds when you use theme from toolkit
Best,
debarisi
I had same problem. I solved it using a Static resource for the Control Style
This is the style i used:
<Style x:Key="autocomplete" TargetType="sdk1:AutoCompleteBox">
<Setter Property="Margin" Value="5,0,5,0"/>
<Setter Property="MinWidth" Value="100"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property ="HorizontalAlignment" Value="Right"/>
</Style>
If I don't use this style my Customs Item are not displayed correctly as I configure in DataItem, instead it show the Class name.

Resources