DevExpress Barbuttonitem together with caliburn micro - wpf

I would like to know. How can I use dxb:Barbuttonitem together with caliburn micro.
I tried to write this code. But unfortunately it did not work.
<Window x:Class="WpfApplication1.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="http://www.caliburnproject.org"
xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon"
Title="ShellView"
Width="300"
Height="300">
<Grid>
<dxb:BarManager Name="barManager1">
<dxb:BarManager.Items>
<dxb:BarButtonItem Name="Connect" Content="barButtonItem1" />
</dxb:BarManager.Items>
<DockPanel >
<dxr:RibbonControl DockPanel.Dock="Top">
<dxr:RibbonDefaultPageCategory Name="ribbonDefaultPageCategory1" Caption="defaultCategory">
<dxr:RibbonPage Caption="Home">
<dxr:RibbonPageGroup Name="ribbonPageGroup1" Caption="Tools">
<dxb:BarButtonItemLink BarItemName="Connect" />
</dxr:RibbonPageGroup>
</dxr:RibbonPage>
</dxr:RibbonDefaultPageCategory>
</dxr:RibbonControl>
<dxr:RibbonStatusBarControl DockPanel.Dock="Bottom" />
</DockPanel>
</dxb:BarManager>
</Grid>
[Export(typeof(IShell))]
public class ShellViewModel : PropertyChangedBase, IShell
{
public void Connect()
{
MessageBox.Show(string.Format("Hello {0}!", "aaa"));
}
public bool CanConnect()
{
return false;
}
}
If I use a standard button, all works fine.

This is not supported by CM since BarButtonItem inherits from FrameworkContentElement (CM supports messages on FrameworkElement only).
The CM forum post can be found here

There's a workaround for this problem that let's you trigger actions from DX's Bar items. You can use a static bar item and put any of standard controls (or buttons) inside then trigger actions from those elements. Example:
<dxb:BarStaticItem x:Name="LoadAllBarItem">
<dxb:BarStaticItem.ContentTemplate>
<DataTemplate>
<Button Content="Load all"
cal:Message.Attach="LoadAction"/>
</DataTemplate>
</dxb:BarStaticItem.ContentTemplate>
</dxb:BarStaticItem>

Related

Simple custom User Control clone its values to various other elements on Frame.GoBack()

I was recently working on a user control, let's name it TestUserControl, and used two of its instances on one page.
While I was testing, I noticed, that when I type something into the values of upper TestUserControl, go to another page then go back to the first page - the second instance of TestUserControl is filled with values that had been typed into the first one (and even elements which are not part of user control of type TestUserControl are affected!).
Here are the screenshots of described behavior .
And the code of a simple project from which this screenshots come:
Landing page:
<Page x:Class="PageNavigation.Pages.Landing"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PageNavigation.Pages"
xmlns:controls="clr-namespace:PageNavigation.Controls"
xmlns:n="clr-namespace:PageNavigation"
mc:Ignorable="d"
d:DesignHeight="200"
d:DesignWidth="800"
Title="Landing">
<Grid Background="White"
ButtonBase.Click="Grid_Click">
<WrapPanel Margin="5">
<TextBlock Margin="0 25"
Text="I am a simple text block" />
<n:NavButton Text="Accounts"
ImageSource="/Images/Accounts.png"
NavUri="/Pages/Accounts.xaml" />
<n:NavButton Text="Bills"
ImageSource="/Images/Billing.png"
NavUri="/Pages/Bills.xaml" />
<n:NavButton Text="Employees"
ImageSource="/Images/Employees.png"
NavUri="/Pages/Employees.xaml" />
<n:NavButton Text="Setting"
ImageSource="/Images/Settings.png"
NavUri="/Pages/Setting.xaml" />
<StackPanel Orientation="Horizontal">
<TextBlock Text="User controls:" />
<controls:TestUserControl Width="150"/>
<controls:TestUserControl Width="150"/>
</StackPanel>
</WrapPanel>
</Grid>
</Page>
using System.Windows;
using System.Windows.Controls;
namespace PageNavigation.Pages
{
public partial class Landing : Page
{
public Landing()
{
InitializeComponent();
}
private void Grid_Click(object sender, RoutedEventArgs e)
{
if (e.OriginalSource is not NavButton ClickedButton)
return;
NavigationService.Navigate(ClickedButton.NavUri);
}
}
}
My testing user control:
<UserControl x:Class="PageNavigation.Controls.TestUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PageNavigation.Controls"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<StackPanel Margin="5">
<TextBox/>
<TextBox/>
<TextBox/>
<StackPanel Margin="10">
<ComboBox>
<ComboBoxItem>Item 1</ComboBoxItem>
<ComboBoxItem>Item 2</ComboBoxItem>
<ComboBoxItem>Item 3</ComboBoxItem>
</ComboBox>
</StackPanel>
<ToggleButton>Toggle me!</ToggleButton>
</StackPanel>
</UserControl>
using System.Windows.Controls;
namespace PageNavigation.Controls
{
public partial class TestUserControl : UserControl
{
public TestUserControl()
{
InitializeComponent();
}
}
}
Navigation button to another pages (these one with images):
using System;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
namespace PageNavigation
{
public class NavButton : ButtonBase
{
static NavButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(NavButton), new FrameworkPropertyMetadata(typeof(NavButton)));
}
public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(NavButton), new PropertyMetadata(null));
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(NavButton), new PropertyMetadata(null));
public static readonly DependencyProperty NavUriProperty = DependencyProperty.Register("NavUri", typeof(Uri), typeof(NavButton), new PropertyMetadata(null));
public ImageSource ImageSource
{
get { return (ImageSource)GetValue(ImageSourceProperty); }
set { SetValue(ImageSourceProperty, value); }
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public Uri NavUri
{
get { return (Uri)GetValue(NavUriProperty); }
set { SetValue(NavUriProperty, value); }
}
}
}
One of example pages which contains back button:
<Page x:Class="PageNavigation.Pages.Employees"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PageNavigation.Pages"
mc:Ignorable="d"
d:DesignHeight="450"
d:DesignWidth="800"
Title="Employees">
<Grid Background="White">
<Button Content="Back"
Padding="3"
Command="NavigationCommands.BrowseBack"
BorderThickness="0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="5,5,0,0" />
<Label Content="Employees"
FontSize="50"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</Page>
using System.Windows.Controls;
namespace PageNavigation.Pages
{
public partial class Employees : Page
{
public Employees()
{
InitializeComponent();
}
}
}
Main window:
<Window x:Class="PageNavigation.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PageNavigation"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Frame Source="/Pages/Landing.xaml" NavigationUIVisibility="Hidden"/>
</Grid>
</Window>
using System.Windows;
namespace PageNavigation
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
I'm using for the navigation System.Windows.Navigation.NavigationService and Frame, which seems to be important, as I couldn't reproduce this bug in a simple application that uses switching ContentControl and custom NavigationService.
When I use binding to view model in TestUserControl values, the problem seems to disappear, but what if I do not need binding, because I use elements of control to manage its internal behavior only - using for example toggle button to hide/show content of a text box field?
I was looking for an explanation for this behavior, but could not find any. I was reading about defining user controls, journal in Navigation Service, Data Context, and keeping alive pages when using Frames, but found nothing about user controls magically cloning their values to other controls.
I understand I could miss something simple or I defined all my user controls wrongly, but... this is not a behavior I would expect from a user control created in the simplest possible way.
I would appreciate it if someone could help me and answer my questions:
why is this happening? Is it a bug in WPF itself?
is this possible to create "safe" user control without necessarily using binding its values to an external source - and how to do it properly?
Sorry if I did not provide all the required information, but I don't know which information will be valuable as it seems to be a vague problem. I will try to answer any questions.
It's the frame journal which stores state for pages which have been shown.
If you don't go back to the previous page in your real app you could do:
NavigationService.RemoveBackEntry()
After you navigate.
That should remove whatever the journal just got.
You could also try giving things explicit X:Name and see if that allows the journal mechanism to differentiate.
Personally, I avoid frames and pages and I suggest you might consider using contentpresenter and usercontrols instead. I prefer viewmodel first navigation.
The discovered workaround is to bind values of controls to properties in code behind (it solves the problem) - at least visually.

UserControl ContentProperty, Content objects are null

I created a custom silverlight UserControl. I need to be able to set its content through a "Child" property. So I used the "[ContentProperty("Child")]" class attribute :
[ContentProperty("Child")]
public partial class SizeableCheckBox : UserControl
{
public SizeableCheckBox()
{
InitializeComponent();
}
public object Child
{
get { return contentControl1.Content; }
set { contentControl1.Content = value; }
}
The XAML of the UserControl looks like that :
<Grid x:Name="LayoutRoot" >
<StackPanel Orientation="Horizontal">
<Border x:Name="brdCheck" />
<ContentControl x:Name="contentControl1" />
</StackPanel
...
</Grid>
Now if I use my UserControl in my application everything works fine (even in VS2010 design mode) :
<my:SizeableCheckBox x:Name="chkTestCheck">
<StackPanel Orientation="Horizontal">
<Image ... />
<Textblock x:Name="txtCheckBoxTest" Text="My Checkbox test" />
</StackPanel>
</my:sizeableCheckBox>
But in my code I have a reference to the "txtCheckBoxTest" but that object is null on runtime. What am I doing wrong?
Thanks
you should be able to go chkTestCheck.txtCheckBoxTest.Text
unless i am misunderstanding the quesiton

New to MVVM Toolkit and need some help getting a simple return value to display

I am very new to Silverlight and WP7 and am writing my first app. I spent a great deal of time trying to figure out what aids to use and my choice came down to Caliburn Micro or MVVM toolkit and after seeing the video on MVVM toolkit, I chose it. But I am having a really difficult time getting it to work like was shown in the Laurent's MIX10 video. I could not find any full example of the code so I had to watch the video almost frame by frame to duplicate what Laurent did and I am only halpf way done. I have the basic code in place and it seems to be hitting my service but is not showing on my WP7 phone emulator. A side question, is the working example posted anywhere? I was hoping someone could look at my code and tell me where I am going wrong. Here it is. When I run the project, there are no errors, the emulator comes up fine but the text does not show that is being returned from the service. I have been developing .Net apps for a long time but am a noob to Silverlight and Asynchronous WCF services. Any help would be appreciated. BTW, the app is very simple, all it does is return a random bible verse from a WCF service I set up at http://www.rjmueller.com/DataAccessService/StoneFalcon.svc and displays it through a method called GetRandomBibleVerseById that takes no parameters and returns an entity called Bible. That's it, very simple. I know the answer is going to be very obvious but what I don't know, I don't know.
This is my ServiceHelper that communicates with my Service:
public class ServiceHelper
{
public void GetRandomBibleVerseById(Action<Bible, Exception> callback)
{
var client = new StoneFalconClient();
client.GetRandomBibleVerseByIdCompleted += (s, e) =>
{
var userCallback = e.UserState as Action<Bible, Exception>;
if (userCallback == null)
{
return;
}
if (e.Error != null)
{
userCallback(null, e.Error);
return;
}
};
client.GetRandomBibleVerseByIdAsync(callback);
}
Here is my MainViewModel:
public class MainViewModel : INotifyPropertyChanged
{
/// <summary>
/// The <see cref="BibleVerse" /> property's name.
/// </summary>
public const string BibleVersePropertyName = "BibleVerse";
private Bible _bibleVerse;
public Bible BibleVerse
{
get
{
return _bibleVerse;
}
set
{
if (_bibleVerse == value)
{
return;
}
_bibleVerse = value;
RaisePropertyChanged(BibleVersePropertyName);
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public string ApplicationTitle
{
get
{
return "RJ's Bible Searcher";
}
}
public string PageName
{
get
{
return "Verse of the Day";
}
}
public MainViewModel()
{
ServiceHelper helper = new ServiceHelper();
helper.GetRandomBibleVerseById((bibleVerse, error) =>
{
if (error != null)
{
//show error
}
else
{
BibleVerse = new Bible();
}
});
}
}
Here is my Xaml page: (the field I am binding to right now is called Text, yes, I know, not the best name, I am going to change that but for now that's what it is)
<phone:PhoneApplicationPage x:Class="BibleSearcher.wp7.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vm="clr-namespace:BibleSearcher.wp7.ViewModel"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait"
Orientation="Portrait"
mc:Ignorable="d"
d:DesignWidth="480"
d:DesignHeight="768"
shell:SystemTray.IsVisible="True"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<UserControl.Resources>
<!--not the best way to do this,
does not allow the constructor to take paramaters, uses default constructor
when the xaml reaches this point, the viewmodel is created-->
<vm:MainViewModel x:Key="MainViewModel" />
</UserControl.Resources>
<!--LayoutRoot contains the root grid where all other page content is placed-->
<Grid x:Name="LayoutRoot"
Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel"
Grid.Row="0"
Margin="24,24,0,12">
<TextBlock x:Name="ApplicationTitle"
Text="RJ's Bible Searcher"
Style="{StaticResource PhoneTextNormalStyle}" />
<TextBlock x:Name="PageTitle"
Text="Verse of the Day"
Margin="-3,-8,0,0"
Style="{StaticResource PhoneTextTitle1Style}" FontSize="48" />
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentGrid"
Grid.Row="1"
DataContext="{Binding Source={StaticResource MainViewModel}}" >
<TextBlock Text="{Binding Path=Text}"
Style="{StaticResource PhoneTextNormalStyle}"
FontSize="28" Margin="17,8,18,8" d:LayoutOverrides="Width" TextWrapping="Wrap" VerticalAlignment="Top" />
</Grid>
</Grid>
Yes, you are binding to a property called "Text" as you point out, but I do not see such a property being exposed by your ViewModel!
Is this actually a property of the BibleVerse object? If so, your binding path should be "BibleVerse.Text"

Opening multiple views by clicking button using MVVM silverlight approach

I want to use MVVM approach to achieve something like below:
I have a MainWindow where i have a 3 Buttons like: a)Customers b) Orders c) Sales
By clicking on button, it should open its respective window/usercontrol xaml with customers details,orders details,sales details.
I have tried everything but culdnt able to do so.
How to achieve this using MVVM pattern. Kindly provide the solution?
Thanks
The answer depends on how you want your Customers, Orders and Sales views displayed. If you want them displayed in the same view, simply add a content control bound to a property in your main ViewModel.
For example, if you're using the MVVM Light Toolkit, your MainPage.xaml might look like...
<UserControl x:Class="MvvmLight2.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Height="300"
Width="300"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Button Content="Customers" Command="{Binding DisplayView}" CommandParameter="Customers" Margin="10" />
<Button Content="Orders" Command="{Binding DisplayView}" CommandParameter="Orders" Margin="10" />
<Button Content="Sales" Command="{Binding DisplayView}" CommandParameter="Sales" Margin="10" />
</StackPanel>
<ContentControl Content="{Binding CurrentView}" IsTabStop="False" Margin="10" />
</StackPanel>
</UserControl>
And your MainPageViewModel would be...
using System.Windows.Controls;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
namespace MvvmLight2.ViewModel
{
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
DisplayView = new RelayCommand<string>(DisplayViewCommandExecute);
}
#region Commands
public RelayCommand<string> DisplayView { get; private set; }
#endregion
#region CurrentView Property
public const string CurrentViewPropertyName = "CurrentView";
private UserControl _currentView;
public UserControl CurrentView
{
get { return _currentView; }
set
{
if (_currentView == value)
return;
_currentView = value;
RaisePropertyChanged(CurrentViewPropertyName);
}
}
#endregion
private void DisplayViewCommandExecute(string viewName)
{
switch (viewName)
{
case "Customers":
CurrentView = new CustomersView();
break;
case "Orders":
CurrentView = new OrdersView();
break;
case "Sales":
CurrentView = new SalesView();
break;
}
}
}
}
This all assumes that you have created views and view models for Customers, Orders, and Sales, and modified the ViewModelLocator to include them.
At this point, if you need to display specific information in your child views, you can create a dependency property in them, and set that from your MainViewModel before you display the view.
You may want to look into the mediator pattern . Common implementations are the Messenger class in the MVVM Light Toolkit and Event Aggregation in PRISM.
One basic workflow using this pattern... Command is called on viewmodel1. Viewmodel1 registers some message with the mediator. Viewmodel2 subscribes to that message and does something in response (like creates new view2 or changes visual state of the view2).
I tried this using Sliverlight Naviagtion Application and MVVM
http://garfoot.com/blog/2010/09/silverlight-navigation-with-the-mvvm-pattern/
Pretty simple example. No frameworks involved as such.
But using a MVVM framework makes life easier for future use.
For MVVM and Prism framework check this link..
http://blog.roboblob.com/2010/10/24/introducing-prism-navigation-framework-for-silverlight-mvvm-applications/

Why do I get a XamlParseException when I inherit a Custom UserControl in another project?

In one project I have an Editor Class:
namespace TestXamlInherit234
{
public class CustomerEditor : BaseEditor
{
public CustomerEditor()
{
TheMessage.Text = "changed222";
}
}
}
which inherits from a WPF User Control in another project:
using System.Windows.Controls;
namespace Core
{
public partial class BaseEditor : UserControl
{
public TextBlock TheMessage
{
get
{
return TheMessage2;
}
}
public BaseEditor()
{
InitializeComponent();
}
}
}
<UserControl x:Class="Core.BaseEditor"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<Grid>
<TextBlock x:Name="TheMessage2" Text="This is in the base editor"/>
</Grid>
</UserControl>
This works when both classes are in the same project but when they are in two different projects, I get a XamlParseException error.
Try:
<Core:BaseEditor x:Class="TestXamlInherit234.CustomerEditor"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Core="yourcorenamespace"
Height="300" Width="300">
<Grid>
<TextBlock x:Name="TheMessage2" Text="This is in the base editor"/>
</Grid>
</Core:BaseEditor>
WPF's support for inheriting any kind of UserControls is very limited. When I did this to work around the lack of generics support I had to define my control in code and derive from ContentControl.

Resources