Ticket T602474
Visible to All Users

Is it possible to use SvgImageSource with the Image control

created 7 years ago

[DevExpress Support Team: CLONED FROM T601990: DxDialogWindow c/w DataLayoutControl]
Hi

I am using a DXDialogWindow to show a Login Dialog at application startup.  Whist there are examples of this in the help files and support tickets I have need allow the login to allow some fixed values when the application is run first time and then later on refer to the application's backend database to verify a user's name and password.  So to that extent the login view needs to have a corresponding viewmodel that can take this scenario into account.  I have therefore opted to use the messenger service to communicate back to the mainViewModel that instantiated the Login Dialog when the login is closed.

The problem I'm currently facing is one of layout.  Firstly I'm using the DataLayout control because I want to make use of its ability to show datavalidation symbols (that works).  I also want to be able to show a simple check or cross image to the side of the User Name and Password Datalayout items that will be shown (with the appropriate image) when the user name and password have been validated.  Only a valid combination will trigger the enablement of the login button.

Before adding the image placeholders into the view the layout (thanks to the datalayout control) worked nicely.  Since adding them it doesn't (see the attached image)

Lastly is it possible to use your SvgImageSource magic to place svg images into the plain image control (which I wish to do dynamically from the viewmodel depending on whether the Username and Password pass validation or fail, thus giving the end user a visual clue to correctness or otherwise).

This is the current xaml I have for the view

XAML
<UserControl xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors" x:Class="ViewToLearn.FishTrackerEnterprises.Modules.Views.LoginView" 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:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm" xmlns:ViewModels="clr-namespace:ViewToLearn.FishTrackerEnterprises.Modules.ViewModels" xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol" xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core" mc:Ignorable="d" DataContext="{dxmvvm:ViewModelSource Type=ViewModels:LoginViewModel}" d:DesignHeight="100" d:DesignWidth="300"> <Grid> <dxlc:DataLayoutControl Orientation="Vertical" AutoGenerateItems="False" CurrentItem="{Binding}" dxe:ValidationService.IsValidationContainer="True"> <dxlc:LayoutGroup Orientation="Vertical"> <StackPanel Orientation="Horizontal" Margin="4"> <dxlc:DataLayoutItem Label="User Name" > <dxe:TextEdit Text="{Binding UserName, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, ValidatesOnDataErrors=True, NotifyOnValidationError=True, ValidatesOnExceptions=True, ValidatesOnNotifyDataErrors=True}" /> </dxlc:DataLayoutItem> <Image x:Name="UserNameImage" Height="16" Width="16" /> </StackPanel> <StackPanel Orientation="Horizontal" Margin="4"> <dxlc:DataLayoutItem Label="Password" > <dxe:TextEdit Text="{Binding Password, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, ValidatesOnDataErrors=True, NotifyOnValidationError=True, ValidatesOnNotifyDataErrors=True}" /> </dxlc:DataLayoutItem> <Image x:Name="PasswordImage" Height="16" Width="16" /> </StackPanel> </dxlc:LayoutGroup> <dxlc:LayoutGroup Orientation="Horizontal" HorizontalAlignment="Right"> <dx:SimpleButton Height="22" Width="75" Content="Login" Command="{Binding LoginCommand}" /> <dx:SimpleButton Height="22" Width="75" Content="Cancel" Command="{Binding CancelCommand}" /> </dxlc:LayoutGroup> </dxlc:DataLayoutControl> </Grid> </UserControl>

and for the sake of completeness this is the viewmodel as it stands

C#
using System; using DevExpress.Mvvm.DataAnnotations; using DevExpress.Mvvm; using DevExpress.Mvvm.POCO; using System.ComponentModel.DataAnnotations; using ViewToLearn.FishTrackerEnterprise.Common; namespace ViewToLearn.FishTrackerEnterprises.Modules.ViewModels { [POCOViewModel(ImplementIDataErrorInfo = true)] public class LoginViewModel { [Required(AllowEmptyStrings = false, ErrorMessage ="User Name is required.")] public virtual string UserName { get; set; } [Required(AllowEmptyStrings = false, ErrorMessage = "Password is required.")] public virtual string Password { get; set; } private bool LoginPassed; public LoginViewModel() { } //public static LoginViewModel Create() //{ // return ViewModelSource.Create(() => new LoginViewModel()); //} public void Login() { SendMessage(LoginMessageType.Succeeded); } public void Cancel() { SendMessage(LoginMessageType.Canceled); } public bool CanLogin() { return LoginPassed; } protected void OnUserNameChanged() { } protected void OnPasswordChanged() { } void SendMessage(LoginMessageType loginMessage) { Messenger.Default.Send(new LoginMessage(loginMessage)); } } }

The Login dialog is called from the main viewmodel like so;

C#
public void Login() { LoginViewModel loginViewModel = ViewModelSource.Create(() => new LoginViewModel()); DialogService.ShowDialog(dialogCommands: null, title: "Login", viewModel: loginViewModel); }

Many thanks

Dom

Answers approved by DevExpress Support

created 7 years ago

Hello,
Sure, you can use our SvgImageSource extension with the standard Image element as well. You can simply define Image's Souce property in the same manner as, for example, BarButtonItem's Glyph property:

XAML
<Image Source="{dx:SvgImageSource Uri=Images/Notebook.svg}" Width="32" />

Thanks,
Kirill

    Show previous comments (1)
    DevExpress Support Team 7 years ago

      Hello,

      To achieve the desired behavior, we can create IValueConverter that will convert string paths to *.svg files from your ViewModel to ImageSource objects as follows:

      C#
      public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var uri = uriConverter.ConvertFrom(value) as Uri; if (uri == null) return null; var absoluteUri = uri.IsAbsoluteUri ? uri : new Uri(baseUri, uri); using(var stream = UriStreamHelper.GetStream(absoluteUri)) { object unused = null; var image = SvgImageHelper.GetOrCreateSvgImage(stream, ref unused); return WpfSvgRenderer.CreateImageSource(image, 1d, null, null, true); } }

      You can find a complete sample in the attachment. Please review it.

      Thanks,
      Alexey

        Hi Alexey

        Thank you so much, this is a perfect solution.

        Regards

        Dom

        DevExpress Support Team 7 years ago

          You are welcome, Dom!

          Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

          Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.