Print scrollview content with full window
In Application window there is scroll view ,
on taking the print out of the window whole scroll view didn't come ,only the window size print is coming ,
I can take the print of scroll view only but is there any way to take the printout of whole scrollview with the window?
PrintDialog printDialog = new PrintDialog();
if (printDialog.ShowDialog() == true)
{
// printDialog.PrintVisual(canvas, "Scrollview Description");
printDialog.PrintVisual(this, this.Title);
}
Answers & Comments...
I didnot get any answer for this question even after editing it, well I look into google several time and after multiple failed attempt finally I got a solution , problem in my code was that ,i used webbrowser control inside scroll view , after reading one solution i remove the scrollview and put code for taking print out of browser control and it works, this is the code i use
mshtml.IHTMLDocument2 doc = webbrwsr.Document as mshtml.IHTMLDocument2;
doc.execCommand("Print", true, null);
for this i have to include one .NET reference Microsoft.mshtml
hope this solution will work for any one else facing the same problem.
by: Answer by Utkarsh for Print scrollview content with full window
Telerik RadGridView does not display at all
Sorry for the naive question...
I am a first time user of the telerik WPF controls, I am following the tutorial here to add a RadGridView to my application...
My wpf application is build using MVVM, I am adding the RadGridView control to one of the views, see implementation below...
<UserControl x:Class="SprintAnalyzer.Module.Presentation.Views.MiddleView"
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:telerik="http://schemas.telerik.com/2008/xaml/presentation"
xmlns:prism="clr-namespace:Microsoft.Practices.Prism.Interactivity.InteractionRequest;assembly=Microsoft.Practices.Prism.Interactivity"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:interactions="clr-namespace:SprintAnalyzer.Module.Presentation.Interactions"
xmlns:Views="clr-namespace:SprintAnalyzer.Module.Presentation.Views" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid x:Name="LayoutRoot" Background="Lavender">
<telerik:RadGridView x:Name="radGridView" AutoGenerateColumns="True"
ItemsSource="{Binding Path=AnalysisResults}" >
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Result}" Header="Result"/>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Category}" Header="Category"/>
</telerik:RadGridView.Columns>
</telerik:RadGridView>
</Grid>
</UserControl>
Note - I have added a reference to xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" my project already has a reference to the Telerik.Windows.Code, Telerik.Windows.Controls.GridView and Telerik.Windows.Controls.Input.
When I run the application, the grid is not displayed at all.
The viewmodel implementation,
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.Events;
using SprintAnalyzer.Common;
using SprintAnalyzer.Common.Service;
using SprintAnalyzer.Module.Presentation.Models;
using SprintAnalyzer.Module.Presentation.Requests;
using SprintAnalyzer.RulesEngine;
using SprintAnalyzer.Common.Events;
namespace SprintAnalyzer.Module.Presentation.ViewModels
{
public class MiddleViewModel : ViewModelBase
{
private readonly IEventAggregator _eventAggregator;
private ICommand _button;
public string Output { get; private set; }
public ICommand OnClick
{
get { return _button; }
set
{
_button = value;
RaisePropertyChangedEvent("OnClick");
}
}
public MiddleViewModel(IApplicationContextService contextService, IEventAggregator eventAggregator)
{
this._contextService = contextService;
this._eventAggregator = eventAggregator;
this.OnClick = new DelegateCommand(this.Button_Clicked);
_eventAggregator.GetEvent<AnalysisRunTrigger>().Subscribe(ExecuteAnalysisRunTrigger, ThreadOption.BackgroundThread);
_eventAggregator.GetEvent<AnalysisResultEvent>().Subscribe(OnAnalysisRunResult, ThreadOption.UIThread);
_eventAggregator.GetEvent<ExceptionRaisedEvent>().Subscribe(OnExceptionRaised,
ThreadOption.UIThread);
this.AnalysisResults = new ObservableCollection<AnalysisResult>();
}
private void OnExceptionRaised(ExceptionDetail obj)
{
// Removed for now
}
private void OnAnalysisRunResult(AnalysisResult analysisResult)
{
AnalysisResults.Add(analysisResult);
}
private static Person CreatePerson()
{
// Removed for now
}
private void SetPeopleExecute()
{
// Removed for now
}
private void GetPersonCallback(Person p)
{
// Removed for now
}
private void CancelCallback()
{
// Removed for now
}
private ObservableCollection<AnalysisResult> _analysisResults;
public ObservableCollection<AnalysisResult> AnalysisResults
{
get
{
return _analysisResults;
}
set
{
_analysisResults = value;
RaisePropertyChangedEvent("AnalysisResults");
}
}
private void ExecuteAnalysisRunTrigger(string triggerState)
{
try
{
switch (triggerState)
{
case "StartAnalyzis":
rulesFactory.Execute();
break;
}
}
catch (Exception ex)
{
_eventAggregator.GetEvent<ExceptionRaisedEvent>().Publish(new ExceptionDetail() { Message = ex.Message });
}
}
private string _message;
private readonly IApplicationContextService _contextService;
public string Message
{
get { return _message; }
set
{
_message = value;
RaisePropertyChangedEvent("Message");
}
}
private void Button_Clicked()
{
//throw new NotImplementedException();
}
}
}
Note that the AnalysisResults is ObservableCollection...
If I take the RadGridView out of the equation and use the good old Wpf GridView control, my application works, I can see the grid load up with the values for the same code...
What am I missing?
No Answer and comments so far
Instantiate IUnitOfWork for each ViewModels in WPF/Prism app
I have lots of repositories like this:
public class PersonRepository : IPersonRepository
{
private readonly IUnitOfWork _unitOfWork;
public PersonRepository(IUnitOfWork instance)
{
_unitOfWork = instance;
}
//Remove, Get methods...
public void Add(Person p)
{
_unitOfWork.Context.People.Add(p);
}
}
and Unit of work class like this:
public class UnitOfWork : IUnitOfWork, IDisposable
{
public UnitOfWork(){ }
private readonly HezarehContext _context = new HezarehContext();
public HezarehContext Context
{
get
{
return _context;
}
}
public int Save()
{
return _context.SaveChanges();
}
public void Initialize()
{
Context.Database.Initialize(false);
}
#region IDisposable Members
public void Dispose()
{
_context.Dispose();
}
#endregion
}
Now i want each time my ViewModels gets resolved, a new IUnitOfWork
instantiated. Most of my ViewModels are like this:
public class PeopleMainViewModel : NotificationObject
{
// both of repositories must have same instance of IUnitOfWork
private readonly IPersonRepository _personRepository = ServiceLocator.Current.GetService<IPersonRepository>();
private readonly ICategoryRepository _categoryRepository = ServiceLocator.Current.GetService<ICategoryRepository>();
public PeopleMainViewModel()
{
InitializeView();
}
// add, edit, remove commands ...
}
ViewModels always gets resolved using Unity Container like this:
Container.RegisterType<IPersonRepository, PersonRepository>();
// resolve in InjectionProperty...
Container.RegisterType<Object, PeopleMainView>("PeopleMainView", new InjectionProperty(PeopleMainView.DataContextProperty.Name, Container.Resolve<PeopleMainViewModel>();
And my question is, How and Where i Register my ViewModel
s and IUnitOfWork
to have IUnitOfWork
instance for each of them?
Answers & Comments...
If I understand your question, just register your IUnitOfWork
the same way (and same place) you register the repository in your above example. You don't need to register your ViewModels based on your current design since you aren't using an Interface.
Container.RegisterType<IUnitOfWork, UnitOfWork>();
And continue to have your repositories accept the IUnitOfWork
in the constructor. This will allow Unity to use constructor injection to provide a new instance of IUnitOfWork
each time it resolves a repository. By default, you'll get a new instance of the IUnitOfWork
each time. If you'd like to have a singleton IUnitOfWork
, you would have to say so when you register the IUnitOfWork
like this:
Container.RegisterType<IUnitOfWork, UnitOfWork>(new ContainerControlledLifetimeManager());
If you want to read up on Lifetime Managers, you can do so here.
I would also recommend changing your ViewModels to take the repositories in as Constructor Parameters, like this if you are going to Resolve them (so Unity will do the work without you referencing the ServiceLocator
directly)
public PeopleMainViewModel(IPersonRepository personRepo, ICategoryRepository categoryRepo)
{
...
}
by: Answer by Brian S for Instantiate IUnitOfWork for each ViewModels in WPF/Prism app
Update:
There is another solution here in unity.codeplex discussions.
I finally found a solution.
There is a feature in Unity
container that let you pass parameters while resolving a Type
. by changing constructor of ViewModels to this:
public class PeopleMainViewModel : NotificationObject
{
private readonly IPersonRepository _personRepository = null;
private readonly ICategoryRepository _categoryRepository = null;
public PeopleMainViewModel(IUnityContainer container, IUnitOfWork unitOfWork)
{
// now both of repositories have same instance of IUnitOfWork
_personRepository = container.Resolve<IPersonRepository>(new ParameterOverride("unitOfWork", unitOfWork));
_categoryRepository = container.Resolve<ICategoryRepository>(new ParameterOverride("unitOfWork", unitOfWork));
InitializeView();
}
// add, edit, remove commands ...
}
problem solved. now _personReposiotry
and _categoryRepository
have reference to same instance of unitOfWork
.
by: Answer by Jalalx for Instantiate IUnitOfWork for each ViewModels in WPF/Prism app
Writing a 2D array of colors to a WPF image
I have what is essentially a 2-dimensional array of colors with each indices representing the pixel and the value being the color of that pixel. For simplicity, let's imagine a 3x3 pixel array that basically has 1-pixel row of red, a 1-pixel row of green and a 1-pixel row of blue:
Color[,] colorArray = new Color[3,3];
for (int i = 0; i < 3; ++i)
{
colorArray[0,i] = Colors.Red;
colorArray[1,i] = Colors.Green;
colorArray[2,i] = Colors.Blue;
}
I have a XAML file with an Image (again, for simplicity, let's assume that the image is also 3x3 pixels). How do I go about writing the above pixel data into something that can be showed in that image file?
Edit:
I've tried using both WriteableBitmaps
and BitmapSources
but can't seem to get them working. For example, the following code (where I'm just trying to paint the whole screen yellow) results in a white image (borrowed from here).
BitmapSource Example
uint[] pixelData = new uint[width * height];
for (int y = 0; y < height; ++y)
{
int yIndex = y * width;
for (int x = 0; x < width; ++x)
{
pixelData[x + yIndex] = (0 << 24) + (255 << 16) + (255 << 8) + 255;
}
}
var bmp = BitmapSource.Create(width, height, dpi, dpi, PixelFormats.Bgra32, null, pixelData, width * 4);
TestImage.Source = bmp;
WriteableBitmap Example
WriteableBitmap wb = new WriteableBitmap(width, height, dpi, dpi, pf, null);
byte[] pixelData = new byte[height * width * 4];
for (int i = 0; i < (int)wb.Height; i++)
{
for (int j = 0; j < (int)wb.Width; j++)
{
var color = colors[i, j];
var idx = j * 4 + i * width * 4;
byte blue = color.B;
byte green = color.G;
byte red = color.R;
pixelData[idx] = blue;
pixelData[idx + 1] = green;
pixelData[idx + 2] = red;
pixelData[idx + 3] = 255;
//byte[] colorData = { blue, green, red, 255 };
//Int32Rect rect = new Int32Rect(j, i, 1, 1);
//wb.WritePixels(rect, colorData, 4, 0);
}
}
Int32Rect rect = new Int32Rect(0, 0, width, height);
wb.WritePixels(rect, pixelData, 4, 0);
TestImage.Source = wb;
Answers & Comments...
This blog describes how to use BitmapSource to create an Image from a byte array with pixels.
Here's the code taken from that blog:
double dpi = 96;
int width = 128;
int height = 128;
byte[] pixelData = new byte[width*height];
for (int y = 0; y < height; ++y)
{
int yIndex = y * width;
for (int x = 0; x < width; ++x)
{
pixelData[x + yIndex] = (byte) (x + y);
}
}
BitmapSource bmpSource = BitmapSource.Create(width, height, dpi, dpi,PixelFormats.Gray8, null, pixelData, width);
by: Answer by Eirik for Writing a 2D array of colors to a WPF image
Use WriteableBitmap
class. WritePixels
method is exactly what you need. (msdn)
Your example:
WriteableBitmap wb = new WriteableBitmap(3, 3, 96, 96, PixelFormats.Bgra32, null);
for (int i = 0; i < (int) wb.Height; i++)
{
byte blue = (byte) (i == 2 ? 255 : 0),
green = (byte) (i == 1 ? 255 : 0),
red = (byte) (i == 0 ? 255 : 0);
byte[] colorData = {blue, green, red, 255};
for (int j = 0; j < (int) wb.Width; j++)
{
Int32Rect rect = new Int32Rect(j, i, 1, 1);
wb.WritePixels(rect, colorData, 4, 0);
}
}
img.Source = wb;
But if you want to draw a big picture you shouldn't write one pixel everytime. It may be very slow. Instead you should fill byte array and copy it to your instance of WritableBitmap
by portions.
by: Answer by Chepene for Writing a 2D array of colors to a WPF image
The following code works with a bitmap source and 32-bit colors:
var height = colorArray.GetUpperBound(0) + 1;
var width = colorArray.GetUpperBound(1) + 1;
var pixelFormat = PixelFormats.Bgra32;
var stride = width * 4; // bytes per row
byte[] pixelData = new byte[height * stride];
for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
{
var color = colorArray[y, x];
var index = (y * stride) + (x * 4);
pixelData[index] = color.B;
pixelData[index + 1] = color.G;
pixelData[index + 2] = color.R;
pixelData[index + 3] = color.A; // color.A;
}
}
var bitmap = BitmapSource.Create(width, height, 96, 96, PixelFormats.Bgra32, null, pixelData, stride);
Image.Source = bitmap;
by: Answer by sohum for Writing a 2D array of colors to a WPF image
Restricting a WPF Textbox to integers by swallowing an exception
I've written the following to restrict a WPF textbox to only accept integers and also only accept a number less than or equal to 35:
In my WindowLoaded event I create a handler for 'OnPaste':
DataObject.AddPastingHandler(textBoxWorkflowCount, OnPaste);
OnPaste consists of the following:
private void OnPaste(object sender, DataObjectPastingEventArgs e)
{
if (!IsNumeric(e.Source.ToString(), NumberStyles.Integer)) e.Handled = true;
}
and our function to force numerics only is as follows:
public bool IsNumeric(string val, NumberStyles numberStyle)
{
double result;
return double.TryParse(val, numberStyle, CultureInfo.CurrentCulture, out result);
}
The specific textbox that is having the error should also be limited to a number <=35. To do this I've added the following TextChanged event:
private void TextBoxWorkflowCountTextChanged(object sender, TextChangedEventArgs e)
{
try
{
if (textBoxWorkflowCount == null || textBoxWorkflowCount.Text == string.Empty || Convert.ToInt32(textBoxWorkflowCount.Text) <= 35) return;
MessageBox.Show("Number of workflow errors on one submission cannot be greater then 35.", "Workflow Count too high", MessageBoxButton.OK, MessageBoxImage.Warning);
textBoxWorkflowCount.Text = "";
}
catch(Exception)
{
// todo: Oh the horror! SPAGHETTI! Must fix. Temporarily here to stop 'pasting of varchar' bug
if (textBoxWorkflowCount != null) textBoxWorkflowCount.Text = "";
}
}
Although this does the job and works it's very nasty/hackish and I would love to know how it could be done better for sake of improving myself... Especially so without having to swallow an exception.
Answers & Comments...
Does this work for you? Replace the content of TextBoxWorkflowCountTextChanged
with this:
if (textBoxWorkflowCount == null || textBoxWorkflowCount.Text == string.Empty) return;
int workflowcount = 36;
if (int.TryParse(textBoxWorkflowCount.Text, out workflowcount) && workflowcount > 35) {
MessageBox.Show("Number of workflow errors on one submission cannot be greater then 35.", "Workflow Count too high", MessageBoxButton.OK, MessageBoxImage.Warning);
textBoxWorkflowCount.Text = "";
}
else if (workflowcount == 36) {
textBoxWorkflowCount.Text = "";
}
by: Answer by QtotheC for Restricting a WPF Textbox to integers by swallowing an exception
Based on of QtotheC's, answer I arrived at the following after a bit more refactoring. Adding here for future visitors :)
private void TextBoxWorkflowCountTextChanged(object sender, TextChangedEventArgs e)
{
if (string.IsNullOrEmpty(textBoxWorkflowCount.Text))
return;
int workflowCount;
if (!int.TryParse(textBoxWorkflowCount.Text, out workflowCount) || workflowCount <= 35) return;
MessageBox.Show("Number of workflow errors on one submission cannot be greater then 35.", "Workflow Count too high",
MessageBoxButton.OK, MessageBoxImage.Warning);
textBoxWorkflowCount.Text = "35";
}
by: Answer by Michael for Restricting a WPF Textbox to integers by swallowing an exception
implementing "close window" command with MVVM
So my first attempt did everything out of the code behind, and now I'm trying to refactor my code to use the mvvm pattern, following the guidance of the mvvm in the box information.
I've created a viewmodel class to match my view class, and I'm moving the code out of the code behind into the viewmodel starting with the commands.
My first snag is trying to implement a 'Close' button that closes the window if the data has not been modified. I've rigged up a CloseCommand to replace the 'onClick' method and all is good except for where the code tries to run this.Close()
. Obviously, since the code has been moved from a window to a normal class, 'this' isn't a window and therefore isn't closeable. However, according to mvvm, the viewmodel doesn't know about the view, so i can't call view.Close()
.
Can someone suggest how I can close the window from the viewmodel command?
No Answer and comments so far
What's the best approach to printing/reporting from WPF?
I have an upcoming project which will have to be able to print simple reports from its data. It'll be WPF-based, and I'm wondering which way to go.
I know that WPF introduces its own printing technology (based on XPS) which looks quite easy to use. However, part of me wonders whether it would just be easier to use the ReportViewer control and embed it in a Windows Forms host control, since that will give users the ability to export to a variety of formats as well as print.
Has anyone had any experience with printing/reporting from WPF? Which direction would you recommend?
Answers & Comments...
by: Answer by ubik for What's the best approach to printing/reporting from WPF?
I've reccently accomplished task of developing own reporting system, which basically consist on design enviroment and data Source manager. The first task was to develop WYSWIG-like design enviroment. I've done this using GDI+, without even bothering about printing, as it came out printing/generating print preview was easiest than i expected, In general it only takes to draw all things on screen to graphics object of printing event.
I think that in case of WPF it would be similar, so all you should worry about is to display you report on screen and printing would be only few lines of code.
by: Answer by MoreThanChaos for What's the best approach to printing/reporting from WPF?
We had this same issue, and ended up using RDLC/ReportViewer for now. There's no native WPF reporting tool (that I know of) and RDLC is pretty simple to use, and is free. The runtime overhead for it is small (around 2Mb) but you must remember to distribute it as it isn't part of the .NET Framework.
by: Answer by Bob King for What's the best approach to printing/reporting from WPF?
Limitations of RDL
I originally went with RDLC/ReportViewer for printing with WPF but found it very limiting. Some of the limitations I found were:
- RDL could only create the most boring of reports
- It was much more work to create a report using RDL than in straight WPF: The design tools are very primitive compared to Expression Blend and RDL deals only in tables
- I didn't have the ability to use ControlTemplates, DataTemplates, Styles, etc
- My report fields and columns could not effectively resize and rearrange based on data size
- Graphics had to be imported as images - it could not be drawn or edited as vectors
- Positioning of items required code-behind rather than data binding
- Lack of transforms
- Very primitive data binding
Printing directly from WPF is very easy
Because of these limitations I looked into creating reports using pure WPF and discovered it was really quite trivial. WPF allows you to implement your own DocumentPaginator
subclass that can generate pages.
I developed a simple DocumentPaginator subclass that takes any Visual, analyzes the visual tree, and hides selected elements to create each page.
DocumentPaginator details
Here is what my DocumentPaginator subclass does during initialization (called when first PageCount is fetched, or during the first GetPage() call):
- Scans the visual tree and makes a map of all scrolled panels inside ItemsControls
- Starting with the outermost, makes items in the ItemsControls invisible last to first until the Visual fits on a single page without any need to scroll. If the outermost can't be reduced enough, reduces inner panels until it succeeds or has only one item at each level. Record the set of visible items as the first page.
- Hide the lowest-level items that have already been shown on the first page, then make subsequent items visible until they no longer fit on the page. Record all but the last-added item as the second page.
- Repeat the process for all pages, storing the results in a data structure.
My DocumentPaginator's GetPage method is as follows:
- Look up the given page number in the data structure generated during initialization
- Hide and show items in the visual tree as indicated in the data structure
- Set PageNumber and NumberOfPages attached properties so report can display page numbering
- Flush the Dispatcher (
Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => {} ));
) to get any background rendering tasks to complete - Create a Rectangle the size of the page whose VisualBrush is the visual being printed
- Measure, Arrange, and UpdateLayout the rectangle, then return it
This turned out to be quite simple code, and allowed me to turn practically anything I could create with WPF into pages and print it.
Additional reporting support
Now that my paginator is working, I no longer have to worry very much about whether I am creating my WPF content for screen or paper. In fact, often UI that I build for data entry and editing also works very well for printing.
From there I added a simple toolbar and some code behind, resulting in a full-fledged reporting system built around WPF that was far more capable than RDL. My reporting code can export to files, print to the printer, cut/paste page images, and cut/paste data for Excel. I can also switch any of my UI to "print view" with a click of a checkbox to see what it will look like if printed. All this in just a few hundred lines of C# and XAML!
At this point I think the only feature RDL has that my reporting code doesn't have is the ability to generate a formatted Excel spreadsheet. I can see how this could be done but so far there has been no need - cutting and pasting the data alone has been enough.
From my experience my recommendation would be to write a paginator, then start using WPF itself to create your reports.
by: Answer by Ray Burns for What's the best approach to printing/reporting from WPF?
Look at http://wpfreports.codeplex.com/
by: Answer by Lukas Cenovsky for What's the best approach to printing/reporting from WPF?
Without getting into a whole political discussion about the future of WPF, the best option we found was to wrap the ReportViewer in a Windows Forms host control.
http://blog.pineywoodstech.com/index.php/2012/01/using-microsoft-reportviewer-with-wpf/
by: Answer by Doug for What's the best approach to printing/reporting from WPF?
I think that you may save tons of time if you use some ready reporting tool for your task, for example:
SharpShooter Reports.WPF, a reports generator allowing you to build various reports in intuitive designer and display them in WPF applications. WPF Viewer already comes with all main functions your final users may want to use: printing from the toolbar, exporting to most popular formats, etc.
And if you decide to use SSRS as your reporting tool in WPF app, the best option will be WPF Viewer for Reporting Services, a native WPF component allowing you to integrate SSRS into WPF applications.
We understand this can sound like an ad :), but we did these products to solve such tasks as you have and we hope that it will really help you!
by: Answer by PerpetuumSoft for What's the best approach to printing/reporting from WPF?
WPF Animation Only Firing Once
I have a small ellipse that I want to flash every time a dependency property gets set to true. Because the property can very quickly go from true back to false in a matter of milliseconds, I need to do this with an animation and not a simple style datatrigger. Basically, I just want the true value to ping an animation on the ellipse.
<Ellipse Height="10" Width="10" Stroke="#FFFFFFFF" Margin="5,3,0,0">
<Ellipse.Fill>
<SolidColorBrush />
</Ellipse.Fill>
<Ellipse.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding IsReceiving}" Value="True" >
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="Fill.Color">
<ColorAnimationUsingKeyFrames.KeyFrames>
<DiscreteColorKeyFrame KeyTime="0:0:0" Value="Red"/>
<DiscreteColorKeyFrame KeyTime="0:0:0.25" Value="Transparent"/>
</ColorAnimationUsingKeyFrames.KeyFrames>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
This animation seems to work, but it only fires the first time the value reaches true. Am I missing something?
Answers & Comments...
You'll need to supply the definition for the IsReceiving property to be sure. Based on the assumption that you've got a property (IsReceiving) that toggles between True and False which will trigger this animation effect: If you're only seeing the effect triggered once then:
1) Check that the property is either a DependencyProperty or utilizing INotifyPropertyChanged correctly to signal updates to the View.
2) Check that the property setter is actually changing from True to False and back.
by: Answer by Steve Py for WPF Animation Only Firing Once
Python or WPF reporting application
I have an existing VS-2008 Windows application with back-end MySQL Server 5.5. The existing application uses Crystal Reports for reporting. I want to get rid of Crystal Reports and want to use another tool that seamlessly integrates with VS-2010 Express. I want to remove reporting options from my existing application and want to write a new WPF reporting application using VS-2010 Express. I want a free tool but as I am using MySQL, tools like SSRS are not useful for me.
What are the options? I am planning the other way round by writing a Python reporting application powered by any open-source Python reporting tool.
Answers & Comments...
For WPF you can use http://wpfreports.codeplex.com/ for simple reports or follow this article instructions to make you own: http://janrep.blog.codeplant.net/post/WPF-Multipage-Reports-Part-I.aspx
I've used SSRS, but only the RDLC part (you can use it with any datasource), but not very happy with the results and WPF does not have a native RDLC ReportViewer.
Also check this related question What's the best approach to printing/reporting from WPF?
by: Answer by Eduardo Molteni for Python or WPF reporting application
Why not have both? IronPython is a python implementation on top of .NET. It allows you to write code that is totally python, but gives you access to all of .NET, including WPF.
For a quick look at what this looks like, here is a basic WPF project using ironpython.
by: Answer by Wilduck for Python or WPF reporting application
If you will not find a suitable open source solution, you can have a look at our products:
SharpShooter Reports.WPF – a reporting engine supporting all .NET data sources and allowing you to display reports in WPF applications. If you ever need to display reports on application built on other technologies, the product has Silverlight, ASP.NET, HTML5 (JavaScript), and Win Forms Viewers.
If you decide to use SSRS as your reporting tool, you can take advantage of WPF Viewer for Reporting Services – a native WPF control allowing you to display SSRS reports in WPF applications.
by: Answer by PerpetuumSoft for Python or WPF reporting application
Adding a custom control to a stackpanel from another class
Hello and thanks for your help.
I have a window with a stackpanel named stackpanel and I have added some custom controls to it in xaml which works great.
Now my program dynamically creates some user controls (with buttons) inside the stackpanel. I want to be able to click a button inside my user control and dynamically add another control to the stackpanel.
I can't seem to get this to work since it is in a different class. How can I add a control to the stackpanel from another control? I couldn't figure out how to use directcast either.
Thank you!
Answers & Comments...
The stackpanel needs to offer a method (let's call it myCreateMethod in this example) to create the control and the method must be accessible by the user control. When you create the user control, pass it a handle to your stackpanel, so e.g.
MyUserControl mycontrol = new MyUserControl(this);
Inside your user control you store the reference:
Stackpanel parent;
public MyUserControl(Stackpanel parent){
this.parent = parent;
}
And then you can call the method to create the control like this:
parent.myCreateMethod();
I hope that gives enough insight to adapt the example to your needs.
EDIT: You could obviously pass details about the new control as parameter(s) to myCreateMethod(). Or you create the new control in the user control, pass it along the the stackpanel and myCreateMethod() "only" displays it.
by: Answer by Jan for Adding a custom control to a stackpanel from another class
You could take advantage of events bubbling up to your stack panel. Try to search for "bubble button click event in wpf" in your favorite search engine.
Here's a quick sample from MSDN (below). The only difference I can see is that the buttons are defined in a UserControl
that you add dynamically to your StackPanel
, which shouldn't affect now event bubbling would work. I'm sure you can figure out how to adapt it to your use case.
XAML:
<Border Height="50" Width="300" BorderBrush="Gray" BorderThickness="1">
<StackPanel x:Name="stackpanel" Background="LightGray" Orientation="Horizontal"
Button.Click="CommonClickHandler">
<Button Name="YesButton" Width="Auto" >Yes</Button>
<Button Name="NoButton" Width="Auto" >No</Button>
<Button Name="CancelButton" Width="Auto" >Cancel</Button>
</StackPanel>
</Border>
C# Backend:
private void CommonClickHandler(object sender, RoutedEventArgs e)
{
FrameworkElement feSource = e.Source as FrameworkElement;
switch (feSource.Name)
{
case "YesButton":
// do something here ...
break;
case "NoButton":
// do something ...
break;
case "CancelButton":
// do something ...
break;
}
e.Handled=true;
}
by: Answer by Kshitij Mehta for Adding a custom control to a stackpanel from another class
How long do i have to wait for a NHibernate version which supports ObservableCollection?
I'm developing with WPF and NHibernate. Best thing to bind Collections to WPF-Lists is the ObservableCollection. NHibernate does not support this; deals only with IList.
How long do I have to wait for a NHibernate version which supports ObservableCollection?
Answers & Comments...
NHibernate project is a mature and open-source project and many big projects depend on it, so its development will never stop. Logically NHibernate will not support ObservableCollection. (I am not sure).NHibernate data-structures are very abstract so it fits with every apllication
by: Answer by sleiman jneidi for How long do i have to wait for a NHibernate version which supports ObservableCollection?
It supports ObservableCollections. Please check http://code.google.com/p/unhaddins/
In here, the NHibernate community puts everything that is out of the scope of the NHibernate core (It's unofficial but maintained by the same community).
Hope it helps.
by: Answer by ivowiblo for How long do i have to wait for a NHibernate version which supports ObservableCollection?
How to combine NHibernate Fluent and the VmWrapper-Classes from the WPF-NHibernate Toolkit?
I'm currently experimenting with the WPF NHibernate toolkit and I have to say: it's a cool piece of software.
The thing is I am stuck with is. The fact that I use Fluent for NHibernate and with Fluent the view model classes (Mappingfiles) have to be inherited from ClassMap. Where do I have to do this change?
Any help is very appreciated.
Answers & Comments...
only the mapping classes must inherit from ClassMap<> not the viewmodels which have nothing to do with persistence. If you want to persist viewmodels you have to write viewmodelmap classes.
by: Answer by Firo for How to combine NHibernate Fluent and the VmWrapper-Classes from the WPF-NHibernate Toolkit?
Why don't FontWeights work in DrawText/DrawingVisual?
I have a drawText field, and I am using FontWeights.Bold, if I change it to SemiBold, Medium or ExtraBold, it doesn't seem to make a difference. For some reason, every bold-type is the same level of weight. The problem I have is normal weight is too light, and bold weight is too heavy, so I want to use SemiBold; but it doesn't make a diff.
Answers & Comments...
Have you tried something like this just as an example
System.Drawing.Font newFont = new Font
(
"Verdana", 10f, System.Drawing.FontStyle.Bold,
System.Drawing.GraphicsUnit.Point, 178, false
);
Would also love to see some of your sample code to make sure that I am on the same page as you are in regards to the issue that you are having..
by: Answer by DJ KRAZE for Why don't FontWeights work in DrawText/DrawingVisual?
Not all fonts are created equal. The fonts themselves define what kinds of "things" (weight, width, slope), and WPF does its best to most closely match what you are looking for.
Take a look at this whitepaper about the font matching/selection process used by WPF. It is on a blog from Mikhail Leonov, a developer on the WPF text team.
by: Answer by Wonko the Sane for Why don't FontWeights work in DrawText/DrawingVisual?
Create Infrastructural window that can be changed
Until now I've worked in Winforms.
I have a good UI infrastructure of a Map.
The base form hold controls like lines (roads,Paths, etc), text boxes, labels, etc.
The controls are arranged to show my map.
The map can be changed. Because of this, the developer inherits from the base form and works with the Winform design.
He can change the map by moving, replacing and adding UI controls and changing UI controls' properties.
Now in wpf the inheritance is disabled and I need a design idea to help me.
Answers & Comments...
WPF actually has a much cleaner way of accomplishing what you're after using what are known as Control Templates. There is a bit of extra work to set it up, but it gives you the ability to fully 'reskin' a functional control. The downside is that visual designer support for editing control templates is not great in Visual Studio. If you need designer support, you'll want to use Expression Blend (which has excellent support for defining a new control template, including creating a copy of the 'default' template for your control to use as a base.)
This is different from the WinForms approach (which basically takes advantage of the way the code-behind is generated to set properties multiple times), but it's also significantly less fragile. In WinForms things can get pretty ugly if you change the base Form too much. The downside is that you don't get the same 'visual inheritance' effect where you can actually add a visual element to the base and suddenly have it appear in your descendents.
by: Answer by Dan Bryant for Create Infrastructural window that can be changed
Wpf tool kit datagrid DataGridCheckBoxColumn on_click event:
I want to get the selected rows, but selecteditems has only one row. I want get the all the checked item. I think I need to add event handler when the checkbox is clecked and then collect them all. How do I do this in a best way?
Answers & Comments...
Are you using databinding to populate your DataGrid? If so, binding the checked value of your column to a bool in your backing object is probably the "best" (as in: best-practices) way to do this. Here is some example code:
<Window x:Class="CheckGridSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tk="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
Title="Window1" Height="300" Width="300">
<StackPanel>
<tk:DataGrid ItemsSource="{Binding}" AutoGenerateColumns="False">
<tk:DataGrid.Columns>
<tk:DataGridTextColumn Header="Name" Binding="{Binding Name}" />
<tk:DataGridCheckBoxColumn Header="Selected" Binding="{Binding IsChecked}" />
</tk:DataGrid.Columns>
</tk:DataGrid>
<Button Content="Which Items Are Checked?" Click="Button_Click" />
</StackPanel>
</Window>
using System;
using System.Linq;
using System.Text;
using System.Windows;
namespace CheckGridSample
{
public partial class Window1
{
public Window1()
{
InitializeComponent();
DataContext = new[]
{
new MyModel {Name = "Able"},
new MyModel {Name = "Baker", IsChecked = true},
new MyModel {Name = "Charlie"}
};
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var builder = new StringBuilder();
foreach (var item in ((MyModel[]) DataContext).Where(m => m.IsChecked))
builder.Append(Environment.NewLine + item.Name);
MessageBox.Show("Checked:" + builder);
}
}
public class MyModel
{
public string Name { get; set; }
public bool IsChecked { get; set; }
}
}
by: Answer by Joseph Sturtevant for Wpf tool kit datagrid DataGridCheckBoxColumn on_click event:
This may help you!!!
Similar question here also
by: Answer by viky for Wpf tool kit datagrid DataGridCheckBoxColumn on_click event:
How to Bind my list to a combobx in WPF
I want to fill combobox content with my list in WPF. I can do it normally in winform but wpf looks a bit different..
I dont create any code in XAML. whole controls create dynamically and at run time..
so here is my code
cmbKriterKategori is a combobox.
cmbKriterKategori.DisplayMemberPath = "Value";
cmbKriterKategori.SelectedValuePath = "Key";
cmbKriterKategori.ItemsSource = yHelper.GetCriterList().ToList();
an error occours
Items collection must be empty before using ItemsSource.
and I also tried like that
cmbKriterKategori.DisplayMemberPath = "Value";
cmbKriterKategori.SelectedValuePath = "Key";
cmbKriterKategori.DataContext = yHelper.GetCriterList().ToList();
it doesnt occour any error but combobox hasnt any item..
yHelper.GetCriterList().ToList(); this function returns List>
and yHelper.GetCriterList() returns Dictionary
I used that code in winform and it works..
cmbKriterKategori.DisplayMember = "Value";
cmbKriterKategori.ValueMember ="Key";
cmbKriterKategori.DataSource = yhelper.GetCriterList().ToList();
So, What is the problem?
Answers & Comments...
you have to clear your combo items so the Items collection must be empty before using ItemsSource
exception won't be thrown
cmbKriterKategori.Items.Clear();
cmbKriterKategori.DisplayMemberPath = "Value";
cmbKriterKategori.SelectedValuePath = "Key";
cmbKriterKategori.ItemsSource = yHelper.GetCriterList().ToList();
by: Answer by Séddik Laraba for How to Bind my list to a combobx in WPF
WPF DataGrid for Windows.Forms (WinForms) DataGridView.AutoSizeColumnsMode = AllCellsExceptHeader
How do I emulate, in a WPF System.Windows.Controls.DataGrid, the WinForms' Windows.Forms .DataGridView.AutoSizeColumnsMode = AllCellsExceptHeader, aka DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader?
No Answer and comments so far
I need to highlight a listbox element that is referred to by another element
I am trying to do the following. I have a listBox with a DataTemplate that is bound to a list of objects.
I also have another element that is bound to an object. that object contains a property that is a reference to one of the elements in the listbox.
The DataTemplate for the ListBox has a border and I want to make an extra thick border around the list item that is referred to by the other object.
I have been playing around with triggers and such, but I can't seem to get my head around how to solve this problem.
Any suggestions?
Answers & Comments...
Check out DataTemplateSelector. You can select which datatemplate to use based on the bound object's property.
by: Answer by Yeonho for I need to highlight a listbox element that is referred to by another element
Custom button template in WPF
I want to create a simple button template with an image and text inside it. But I want to keep the System button's look and feel.
How do I create it, step by step?
P.S.: I have already tried it with CustomControl
in WPF and BasedOn
property.
Answers & Comments...
I have finally created a Button with image + text inside it:
Below is the Full Code:
Step 1 : Create a new User Control called:ImageButtonUC
<UserControl Name="ImageButton" x:Class="WpfApp.ImageButtonUC"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Button VerticalAlignment="Top" Width="100" Height="25" Click="button_Click">
<Button.Content>
<StackPanel Orientation="Horizontal">
<Image Width="16" Height="16" Margin="5,0,5,0" Source="{Binding ElementName=ImageButton, Path=Image}"/>
<TextBlock Text="{Binding ElementName=ImageButton, Path=Text}"/>
</StackPanel>
</Button.Content>
</Button>
</Grid>
</UserControl>
Step 2: Edit ImageButtonUC.xaml.cs
public partial class ImageButtonUC : UserControl
{
public event RoutedEventHandler Click;
public ImageButtonUC()
{
InitializeComponent();
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(ImageButtonUC), new UIPropertyMetadata(""));
public ImageSource Image
{
get { return (ImageSource)GetValue(ImageProperty); }
set { SetValue(ImageProperty, value); }
}
public static readonly DependencyProperty ImageProperty =
DependencyProperty.Register("Image", typeof(ImageSource), typeof(ImageButtonUC), new UIPropertyMetadata(null));
private void button_Click(object sender, RoutedEventArgs e)
{
if (null != Click)
Click(sender, e);
}
}
Step 3: In your xaml you can use it this way:
Add the namespace as
xmlns:Local="clr-namespace:WpfApp"
And use it as:
<Local:ImageButtonUC x:Name="buttonImg" Width="100" Margin="10,0,10,0" Image="/WpfApp;component/Resources/Img.bmp" Text="Browse..." Click="buttonImg_Click"/>
Note: My Image is loacted in the Resources folder here
Reference:
by: Answer by Archie for Custom button template in WPF
You can do this easily with a style and attached property:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ap="clr-namespace:MyProject.Namespace.Path.To.ButtonProperties">
...
<Style x:Key="ImageButton" TargetType="Button">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Path=(ap:ButtonProperties.Image), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"></Image>
<ContentPresenter Content="{Binding Path=Content, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"></ContentPresenter>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
...
</ResourceDictionary>
and
public class ButtonProperties
{
public static ImageSource GetImage(DependencyObject obj)
{
return (ImageSource)obj.GetValue(ImageProperty);
}
public static void SetImage(DependencyObject obj, ImageSource value)
{
obj.SetValue(ImageProperty, value);
}
public static readonly DependencyProperty ImageProperty =
DependencyProperty.RegisterAttached("Image", typeof(ImageSource), typeof(ButtonProperties), new UIPropertyMetadata((ImageSource)null));
}
Then in markup:
<Button Style="{StaticResource ImageButton}" ap:ButtonProperties.Image="{StaticResource MyImage}" Content="Test">
</Button>
This example looks pretty hideous, but you can easily change the StackPanel
to a Grid
or something similar to constrain the image proportion. Using the ContentPresenter
allows you to preserve the behaviour of a button allowing you to put any UIElement
inside, and retaining Command support etc.
by: Answer by jeffora for Custom button template in WPF
Error HRESULT 0x88982F72 when trying streaming image file
I'm trying to stream an image file with the simple code below.
Stream stream = File.OpenRead(myFileInfo.ToString());
When I do it, Visual Studio send me an exception.
This file is a simple jpeg.
In Debug mode, I see with the BitmapDecoder class that my file has not Frames. In comparission with other files of same extension, all have one Frame.
I already try the solution using the FileStream class and it doesn't work :'(
My main code is this :
BitmapImage myBitmapImage = new BitmapImage();
using (Stream stream = File.OpenRead(fileInfo.ToString()))
{
myBitmapImage.BeginInit();
myBitmapImage.StreamSource = stream;
myBitmapImage.EndInit();
}
It is written in a converter and naturally is binding to a Image control.
But the exception is throw before set in the Image.Source property at the line below :
myBitmapImage.EndInit();
Another detail : the image file can be open with Photoshop, Paint.net and other programs. When these last save a copy, new files doesn't present problem to open with the same code.
But I can't say to our customers to do this all the time (Approximately 50 times in a day :s).
Thanks.
My excpetion detail below:
System.IO.IOException was unhandled by user code
HResult=-2146232800
Message=Impossible de lire à partir du flux.
Source=PresentationCore
StackTrace:
à System.Windows.Media.ColorContext.GetColorContextsHelper(GetColorContextsDelegate getColorContexts)
à System.Windows.Media.Imaging.BitmapFrameDecode.get_ColorContexts()
à System.Windows.Media.Imaging.BitmapImage.FinalizeCreation()
à System.Windows.Media.Imaging.BitmapImage.EndInit()
à EDIs.Imaging.Converter.UriToBitmapSourceConverter.Convert(Object value, Type targetType, Object parameter, CultureInfo culture) dans C:\Users\Gaet\Documents\Visual Studio 2010\Projects\DotNet\MDP.EDIs\EDIs.Imaging\Converter\UriToBitmapSourceConverter.cs:ligne 40
à System.Windows.Data.BindingExpression.TransferValue(Object newValue, Boolean isASubPropertyChange)
à System.Windows.Data.BindingExpression.Activate(Object item)
à System.Windows.Data.BindingExpression.AttachToContext(AttachAttempt attempt)
à System.Windows.Data.BindingExpression.AttachOverride(DependencyObject target, DependencyProperty dp)
à System.Windows.Data.BindingExpressionBase.OnAttach(DependencyObject d, DependencyProperty dp)
à System.Windows.StyleHelper.GetInstanceValue(UncommonField`1 dataField, DependencyObject container, FrameworkElement feChild, FrameworkContentElement fceChild, Int32 childIndex, DependencyProperty dp, Int32 i, EffectiveValueEntry& entry)
à System.Windows.FrameworkTemplate.ReceivePropertySet(Object targetObject, XamlMember member, Object value, DependencyObject templatedParent)
à System.Windows.FrameworkTemplate.<>c__DisplayClass6.<LoadOptimizedTemplateContent>b__4(Object sender, XamlSetValueEventArgs setArgs)
à System.Xaml.XamlObjectWriter.OnSetValue(Object eventSender, XamlMember member, Object value)
à System.Xaml.XamlObjectWriter.Logic_ApplyPropertyValue(ObjectWriterContext ctx, XamlMember prop, Object value, Boolean onParent)
à System.Xaml.XamlObjectWriter.Logic_DoAssignmentToParentProperty(ObjectWriterContext ctx)
à System.Xaml.XamlObjectWriter.Logic_AssignProvidedValue(ObjectWriterContext ctx)
à System.Xaml.XamlObjectWriter.WriteEndObject()
à System.Xaml.XamlWriter.WriteNode(XamlReader reader)
à System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlReader templateReader, XamlObjectWriter currentWriter)
InnerException: System.Runtime.InteropServices.COMException
HResult=-2003292302
Message=Exception de HRESULT : 0x88982F72
ErrorCode=-2003292302
InnerException:
Answers & Comments...
BitmapImage Art3 = new BitmapImage();
using (FileStream stream = File.OpenRead("c:\\temp\\Album.jpg"))
{
Art3.BeginInit();
Art3.StreamSource = stream;
Art3.EndInit();
}
artwork.Source = Art3;
"artwork" is the XAML object where image is supposed to be shown.
by: Answer by hellzone for Error HRESULT 0x88982F72 when trying streaming image file
Have a look at this blog post by Scott Hanselman Dealing with Images with Bad Metadata - Corrupted Color Profiles in WPF
His suggested fix worked in my case. From the blog:
var bi = new BitmapImage();
bi.BeginInit();
bi.CreateOptions = BitmapCreateOptions.IgnoreColorProfile;
bi.UriSource = new Uri("http://hanselman.com/blog/images/JPGwithBadColorProfile.jpg");
bi.EndInit();
foo.Source = bi;
Hope this helps.
by: Answer by Lou for Error HRESULT 0x88982F72 when trying streaming image file
How to open a WPF exe from within a VB6 dll?
This is a question about design approach. I have limited COM experience and a little WCF experience. My constraints are given by the application environment, but I have some design flexibility.
From within a VB6 dll, I need to start, and communicate with, a WPF application. The WPF application is currently an exe, but I could make it a library if that helped. I would like to provide two way communication between the VB6 dll and the WPF application. I have some flexability to adjust the design of the VB6 dll.
I'm developing C# using in VS2010 and .NET 4.
How many components should I use? Can I start the WPF application In-Proc with the VB6 dll? Should there be a third component between them? Can COM+ play a helpful role? Do I have to make the entire WPF application COM-visible? Is there a down-side to doing this?
I'm looking for a design approach that I can prototype. I'm willing to research the details.
Answers & Comments...
Out of the options available I like the COM option more than the 'start another process' option for the simplicity that the inter 'application' communication will be via method calls rather than WCF or anything similar.
I am assuming that your VB DLL lives in a window'd process and not a service or web application. You would only need to mark any exposed types as COM visible, that is the classes, their argument and return types.
You may have to wrap your WPF UI inside the windows forms ElementHost [1] but I'm not sure, try it and see.
I'm not sure if you saw this [2] in your search, it sounds do-able but unsupported, ok as long as you don't have too much going on.
[1] http://msdn.microsoft.com/en-us/library/system.windows.forms.integration.elementhost.aspx
[2] http://social.msdn.microsoft.com/forums/en-US/wpf/thread/7555ba6a-1359-4dfe-aa23-c31a8f121142/
by: Answer by Adam Straughan for How to open a WPF exe from within a VB6 dll?
I would
- Create a Web Service from the WPF application, using WCF. I would abstract out those aspects of the WPF application which should be accessed remotely. This would explicitly not include any of the user interface code.
- I would create a simple class library project, and use "Add Service Reference" to add a reference to the WCF service.
- I would make the methods of the class library COM-visible
- I would call those methods from VB6
This has the benefit of removing any considerations of user interface from the equation.
by: Answer by John Saunders for How to open a WPF exe from within a VB6 dll?
I work on an application primarily written in VB6 but most of the recent code is written in .net with UI components built in WPF and some WinForms. Datasources for this application are WCF, MSSQL server, and a propritary unix based server. All the WCF calls are made from data access components referenced by the .net UI components.
You can host WPF in VB6 windows or other container controls. Start by getting the Interop Forms Toolkit and build shell user controls to host your WPF controls.
To be able to host WPF in these controls you need to build a WinForms usercontrol which contains a ElementHost, which you can set the content to your WPF usercontrol.
WPF Usercontrol
inside an
Element Host
inside a
WinForms usercontrol
inside a
VB6 usercontrol or
window
The interop toolkit will want to build VB.Net code but you can do it in C#, although I have not tried this. The usercontrols created by the interop toolkit will be exposed as COM components which you can reference VB6 by adding them as components via Project > Components and then you will find them in the toolbox.
In terms of data sources (WCF, databases) etc, you should build all your data access in .net components referenced directly from the UI components, don't try to call back in to VB6 libraries, you will probably just create a mess.
In my application I also have a configuration section which I call from the VB6 application startup which sets up an IoC container for all the .net components.
From a best practice approach I actually would recommend rewriting your VB6 code to .net and putting VB6 out of the picture. If this is not an option then you have a number of options, my explanation is just one of them.
by: Answer by benPearce for How to open a WPF exe from within a VB6 dll?
MeasureOverride and other methods in WPF
I'm having issue with WPF and the way it should be implemented which wondering if experts could advise me. In WPF, in the beginning we keep running into classes which we had never heard of (or let's say it is my case only) and each class has its own new methods.
Today, I'm writing an application using Adorner and now I know I must use MeasureOverride() from FrameworkElement ... yes, I know majority of controls in WPF are from FrameworkElement but how should I know which method should be used?
I see tens of blogs throwing methods and dictating what should be done but what is the best way to know what should be used and how? I guess all I need to know is that how should I know which method is needed from a particular case. I just don't like to mimic what is done here or there. I hope it is clear what I'm trying to say here.
It worries me that things are getting out of hand and there are too much info to catch up with.
Thanks,
Amit
Answers & Comments...
I guess I need to reference my own blog here.
http://csharpramblings.blogspot.ca/2012/05/understanding-wpf-layout-system.html
The article is a short introduction to the WPF layout system, using a custom panel control as an example.
by: Answer by Kendall Frey for MeasureOverride and other methods in WPF
Draw arc with angles ranging from -360 to 360 degrees
I am having some trouble trying to implement drawing an arc. Basically it's supposed to be drawn exactly like how you can draw a 3 point arc in AutoCAD. I can get the arc to draw with start and end angles from from -180 degrees to 360, but if I try to go more than -180, the arc flips around to +180 degrees. My problem is that I need the arc to continue when the angle passes -180. I have everything right in the code (I think) except for calculating the start and end angles. Thanks in advance for any help. Here is my code:
private void DrawArc()
{
//fyi linept is of type List<Point3D>();
Point3D currentPoint = (Point3D)GetPoints(e);
double rad;
Point3D center = GetCenterOfCircle(linept.ElementAt(0), linept.ElementAt(1), currentPoint, out rad);
PieSliceVisual3D circle = new PieSliceVisual3D();
circle.Center = center;
circle.OuterRadius = rad;
circle.InnerRadius = circle.OuterRadius + 3;
circle.StartAngle = (Math.Atan2(linept.ElementAt(0).Y - center.Y, linept.ElementAt(0).X - center.X) * 180 / Math.PI);
circle.EndAngle = (Math.Atan2(currentPoint.Y - center.Y, currentPoint.X - center.X) * 180 / Math.PI);
//I've also tried these next 4 lines to no avail
double startAngle = (Math.Atan2(linept.ElementAt(0).Y - center.Y, linept.ElementAt(0).X - center.X) * 180 / Math.PI);
circle.StartAngle = (startAngle > 0.0 ? startAngle : (360.0 + startAngle));
double endAngle = (Math.Atan2(currentPoint.Y - center.Y, currentPoint.X - center.X) * 180 / Math.PI);
circle.EndAngle = (endAngle > 0.0 ? endAngle : (360.0 + endAngle));
}
Answers & Comments...
Since I actually don't write for AC in C#, I'll give this as a "hint", but I think you'll be able to implement it in your solution.
With my experience writing AC macros, I found it is tremendously beneficial to keep in mind the prompts that are given when you're actually drawing in the environment. AC rarely limits you to one option.
After invoking the arc, the prompts are:
In selecting direction you'll be able to select the tangent angle relative to the starting point.
So, I would select the first and end points, the do direction. Given two vertical aligned lines >90 will be arcing to the left of the lines, and <90 puts you on the right!
by: Answer by Roberto Wilko for Draw arc with angles ranging from -360 to 360 degrees
Issues with EventToCommand for the Loaded event
So I am using GalaSoft's EventToCommand for binding my View's Loaded event to my command in my ViewModel. The binding is working great but my Command is never being executed. The only way I have been able to get this to work is to handle the Loaded event in my View's code behind and then cast my DataContent to my VM and tell it to run my code (which the command is trying to do). Obviously this isnt very nice when trying to do it all MVVM like. FYI I did try the MouseEnter event and that worked great so that makes me think its a timing issue. Also, my View is a user control.
View:
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<cmd:EventToCommand PassEventArgsToCommand="False" Command="{Binding Path=DownloadDataCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
ViewModel:
public RelayCommand DownloadDataCommand
{
get { return new RelayCommand(() => DownloadDataAsync()); }
}
Ive tried calling simple methods that do pretty much nothing and my relay command is still not invoked. So I doubt its the action within the RelayCommand. Does anyone see what I am doing wrong?
No Answer and comments so far
How to bring window to front with wpf and using mvvm
I have a window that essentially runs a timer. When the timer hits 0 I want to bring the window to the front so that it is visible and not hidden behind some other application.
From what I can gather I would simply call window.activate() to accomplish this but with mvvm my view model doesn't have a reference to window.
Answers & Comments...
You could go about it in a couple of ways - adding a reference to the window could work since the viewmodel is not coupled with the view but related to it, but I don't really like that approach since it pretty much does couple your view to your viewmodel - which is not really the point of MVVM
A better approach may be to have your viewmodel raise an event or a command which the view can handle. This way the view gets to decide what UI action is associated with the command/event
e.g. simply
class SomeView
{
void HandleSomeCommandOrEvent()
{
this.Activate();
}
}
Of course how you wire this up is up to you but I'd probably try and get routed commands happening
Edit: You can't really 'bind' a simple event, since it's invoked from the viewmodel.
A simple event based example is just to add the event to the viewmodel and handle it directly ... e.g. imagine the following MainWindow with a ViewModel property
public partial class MainWindow : Window
{
MainWindowViewModel ViewModel { get; set; }
public MainWindow()
{
InitializeComponent();
ViewModel = new MainWindowViewModel();
ViewModel.ShowMessage += ViewModel_ShowMessage;
this.DataContext = ViewModel;
}
void ViewModel_ShowMessage(object sender, ShowMessageEventArgs e)
{
MessageBox.Show(e.Message, "Some caption", MessageBoxButton.OK);
}
}
Then the ViewModel can just fire the event:
// The view model
public class MainWindowViewModel
{
// The button click command
public RelayCommand ButtonClickCommand { get; set; }
// The event to fire
public event EventHandler<ShowMessageEventArgs> ShowMessage;
public MainWindowViewModel()
{
ButtonClickCommand = new RelayCommand(ButtonClicked);
}
void ButtonClicked(object param)
{
// This button is wired up in the view as normal and fires the event
OnShowMessage("You clicked the button");
}
// Fire the event - it's up to the view to decide how to implement this event and show a message
void OnShowMessage(string message)
{
if (ShowMessage != null) ShowMessage(this, new ShowMessageEventArgs(message));
}
}
public class ShowMessageEventArgs : EventArgs
{
public string Message { get; private set; }
public ShowMessageEventArgs(string message)
{
Message = message;
}
}
The XAML would be:
<Button Command="{Binding ButtonClickCommand}">Click me!</Button>
So the button invokes the command, which in turn fires the event which the view (MainWindow) handles and shows a messagebox. This way the view/UI decides on the course of action based on the type of event raised. Of course it could be your timer which fired the event
You can always go down the more involved route such as some of the answers on this question...
WPF MVVM Newbie - how should the ViewModel close the form?
but to be honest, it depends if you really need it - a simple event works well - some people overcomplicate things for the sake of elegance, but at the detriment of simplicity and productivity!
by: Answer by Charleh for How to bring window to front with wpf and using mvvm
XAML "Conditional" Binding
I have a DataTrigger attached to a style for TextBlock, defined as such:
<DataTrigger Binding="{Binding Path=Link, Converter={StaticResource HasContentConverter}}" Value="True">
<Setter Property="TextDecorations" Value="Underline" />
<Setter Property="Cursor" Value="Hand" />
</DataTrigger>
The issue that I'm having is that I have multiple objects that end up using this style, some of which contain a "Link" property, and some of which don't. Whenever the system encounters an object that doesn't, it prints this error in the output window:
BindingExpression path error: 'Link' property not found on 'object' ''DataRowView' (HashCode=53681904)'. BindingExpression:Path=Link; DataItem='DataRowView' (HashCode=53681904); target element is 'TextBlock' (Name=''); target property is 'NoTarget' (type 'Object')
This is expected behaviour, however I'm wondering if there's a way to tell the processor in XAML to only apply if the "Link" property exists (ie. check for the property before attempting to bind, or some other method that doesn't print an error). Is this possible?
Answers & Comments...
Both out of the box and directly it is not possible.
Not out of the box: you can write your own BindingExtension that would behave like that: bind if the prop exists, else ignore. You can also, khem, turn off reporting binding error, but of course that is usually not wanted.
Not directly: you can create an attached attribute of some type, and then set such attribute instead of setting the binding. Your attribute-setter would attach to datacontext-changes and inspect the objects and visual components as they fly around and set the binding or not.
Not directly#2: You can try to "hierarchize" the styles and triggers. As you know, Trigger has a Condition. Split your style in two parts: first is the common style that does not need to be "guarded", and the second one contains features dependent on having "Blargh" property. Set the first style as default/normal. Now create a readonly attached property called "DefinesBlargh" or "HasBlarghDefines" that checks if the target object's datacontext actually has such property. Now add to the first style a trigger that detects whether the styled control has "HasBlarghDefined" equal "true", and in the trigger's action...
...and here's the problem. What to do there? You cannot replace the style again to the second part of the style, as it probably would remove the trigger and in turn deactivate the logic (it would be one-shot). Or, it may simply crash due to the fact of trying to change the style two times in one update sweep. I actually not know what would happend, but I sense "a smell". More over, changing to the second-part would simply erase the common things that the first part set up.
So, if it actually would run and replace the style, you'd have to ENSURE that the original trigger logic and rest of the first style is preserved, I'd suggest using "style inheritace", that is, the based-on style property: http://wpftutorial.net/StyleInheritance.html That is, do not create two separate parts, but rather, make a "base part" with all common things, and a "specialized part" that is based on the first and adds the unsafe extra things. Now dynamically re-replacing to the specialized counterpart is a bit more reasonable.
Or, if you have some control over the layout, you can get smart: Why apply the two styles to the same component? Set the general style on some outer bound of the control and place the extra trigger there, and let the trigger apply the small unsafe second style to the control.
If you really have to target exactly one control with both parts of the style and cannot use "based on" or maybe if it simply does not work etc, you can do another smart trick: use a MultiStyle
that allows you to define a style that mergers two/three/+ other styles into one, and then build a trigger hierarchy as follows:
multitrigger
condition: HasBlarghDefined = TRUE
condition: your own data condition
setter: set style = multistyle of "generalpart" and "usnafepart"
multitrigger
condition: HasBlarghDefined = FALSE
condition: your own data condition
setter: set style = just a generalpart
IMHO, that just have to work.
edit: forgot to past the critical link: The MultiStyle
by: Answer by quetzalcoatl for XAML "Conditional" Binding
Binding ItemsSource of a ComboBoxColumn in WPF DataGrid
I have two simple Model classes and a ViewModel...
public class GridItem
{
public string Name { get; set; }
public int CompanyID { get; set; }
}
public class CompanyItem
{
public int ID { get; set; }
public string Name { get; set; }
}
public class ViewModel
{
public ViewModel()
{
GridItems = new ObservableCollection<GridItem>() {
new GridItem() { Name = "Jim", CompanyID = 1 } };
CompanyItems = new ObservableCollection<CompanyItem>() {
new CompanyItem() { ID = 1, Name = "Company 1" },
new CompanyItem() { ID = 2, Name = "Company 2" } };
}
public ObservableCollection<GridItem> GridItems { get; set; }
public ObservableCollection<CompanyItem> CompanyItems { get; set; }
}
...and a simple Window:
<Window x:Class="DataGridComboBoxColumnApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding GridItems}" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}" />
<DataGridComboBoxColumn ItemsSource="{Binding CompanyItems}"
DisplayMemberPath="Name"
SelectedValuePath="ID"
SelectedValueBinding="{Binding CompanyID}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
The ViewModel is set to the MainWindow's DataContext
in App.xaml.cs:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
MainWindow window = new MainWindow();
ViewModel viewModel = new ViewModel();
window.DataContext = viewModel;
window.Show();
}
}
As you can see I set the ItemsSource
of the DataGrid to the GridItems
collection of the ViewModel. This part works, the single Grid line with Name "Jim" is displayed.
I also want to set the ItemsSource
of the ComboBox in every row to the CompanyItems
collection of the ViewModel. This part does not work: The ComboBox remains empty and in the Debugger Output Window I see an error message:
System.Windows.Data Error: 2 : Cannot
find governing FrameworkElement or
FrameworkContentElement for target
element.
BindingExpression:Path=CompanyItems;
DataItem=null; target element is
'DataGridComboBoxColumn'
(HashCode=28633162); target property
is 'ItemsSource' (type 'IEnumerable')
I believe that WPF expects CompanyItems
to be a property of GridItem
which is not the case, and that's the reason why the binding fails.
I've already tried to work with a RelativeSource
and AncestorType
like so:
<DataGridComboBoxColumn ItemsSource="{Binding CompanyItems,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type Window}}}"
DisplayMemberPath="Name"
SelectedValuePath="ID"
SelectedValueBinding="{Binding CompanyID}" />
But that gives me another error in the debugger output:
System.Windows.Data Error: 4 : Cannot
find source for binding with reference
'RelativeSource FindAncestor,
AncestorType='System.Windows.Window',
AncestorLevel='1''.
BindingExpression:Path=CompanyItems;
DataItem=null; target element is
'DataGridComboBoxColumn'
(HashCode=1150788); target property is
'ItemsSource' (type 'IEnumerable')
Question: How can I bind the ItemsSource of the DataGridComboBoxColumn to the CompanyItems collection of the ViewModel? Is it possible at all?
Thank you for help in advance!
Answers & Comments...
Your ComboBox is trying to bind to bind to GridItem[x].CompanyItems
, which doesn't exist.
Your RelativeBinding is close, however it needs to bind to DataContext.CompanyItems
because Window.CompanyItems does not exist
by: Answer by Rachel for Binding ItemsSource of a ComboBoxColumn in WPF DataGrid
Pls, check if DataGridComboBoxColumn xaml below would work for you:
<DataGridComboBoxColumn
SelectedValueBinding="{Binding CompanyID}"
DisplayMemberPath="Name"
SelectedValuePath="ID">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding Path=DataContext.CompanyItems, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding Path=DataContext.CompanyItems, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
Here you can find another solution for the problem you're facing: Using combo boxes with the WPF DataGrid
hope this helps, regards
by: Answer by serge_gubenko for Binding ItemsSource of a ComboBoxColumn in WPF DataGrid
The documentation on MSDN about the ItemsSource
of the DataGridComboBoxColumn
says that only static resources, static code or inline collections of combobox items can be bound to the ItemsSource
:
To populate the drop-down list, first
set the ItemsSource property for the
ComboBox by using one of the following
options:
- A static resource. For more information, see StaticResource Markup
Extension.- An x:Static code entity. For more information, see x:Static Markup
Extension.- An inline collection of ComboBoxItem types.
Binding to a DataContext's property is not possible if I understand that correctly.
And indeed: When I make CompanyItems
a static property in ViewModel ...
public static ObservableCollection<CompanyItem> CompanyItems { get; set; }
... add the namespace where the ViewModel is located to the window ...
xmlns:vm="clr-namespace:DataGridComboBoxColumnApp"
... and change the binding to ...
<DataGridComboBoxColumn
ItemsSource="{Binding Source={x:Static vm:ViewModel.CompanyItems}}"
DisplayMemberPath="Name"
SelectedValuePath="ID"
SelectedValueBinding="{Binding CompanyID}" />
... then it works. But having the ItemsSource as a static property might be sometimes OK, but it is not always what I want.
by: Answer by Slauma for Binding ItemsSource of a ComboBoxColumn in WPF DataGrid
I realize this question is over a year old, but I just stumbled across it in dealing with a similar problem and thought I would share another potential solution in case it might help a future traveler (or myself, when I forget this later and find myself flopping around on StackOverflow between screams and throwings of the nearest object on my desk).
In my case I was able to get the effect I wanted by using a DataGridTemplateColumn instead of a DataGridComboBoxColumn, a la the following snippet. [caveat: I'm using .NET 4.0, and what I've been reading leads me to believe the DataGrid has done a lot of evolving, so YMMV if using earlier version]
<DataGridTemplateColumn Header="Identifier_TEMPLATED">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox IsEditable="False"
Text="{Binding ComponentIdentifier,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Path=ApplicableIdentifiers, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding ComponentIdentifier}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
by: Answer by RookieRick for Binding ItemsSource of a ComboBoxColumn in WPF DataGrid
Metadata file '.dll' could not be found
I am working on a WPF, C#3.0 Project and I am getting this error:
Error 1 Metadata file
'WORK=-\Tools\VersionManagementSystem\BusinessLogicLayer\bin\Debug\BusinessLogicLayer.dll'
could not be
found C:-=WORK=-\Tools\VersionManagementSystem\VersionManagementSystem\CSC VersionManagementSystem
EDIT:
This is how I reference my usercontrols
xmlns:vms="clr-namespace:VersionManagementSystem"
<vms:SignOffProjectListing Margin="5"/>
It happens after every failed build. The only way I can get the solution to compile is to comment out all my user controls and and built the project, then I uncomment the usercontrols and everything is fine.
I have checked build orders, dependencies configurations.
As you can see it seems to have truncated the dll's absolute path... I have read that there is a bug with the length. Is this a possible problem?
It's very annoying and having to comment, build, uncomment, build is becoming extremely tiresome.
Answers & Comments...
Based on the error message I don't believe the file path is being truncated, it looks to just be incorrect. If i'm reading the message correctly it appears to be looking for the DLL at ...
WORK=-\Tools\VersionManagementSystem\BusinessLogicLayer\bin\Debug\BusinessLogicLayer.dll
This is not a valid path. Is it possible that you have a macro definition in the build process set to an invalid value?
by: Answer by JaredPar for Metadata file '.dll' could not be found
Calender button alignment issue in DateTimePicker
I'm using WPFExtendedtoolkit dll in our project to get DateTimePicker. Problem is the Calender button will not come properly when the calender Pops down, half of the button has been hidden. How can I get calender control?
No Answer and comments so far
How to bind two WPF combo boxes to a single XML file?
I have the following XML file:
<Palettes>
<Palette>
<Primary Name="Black"/>
<Other Name="Blue"/>
<Other Name="Red"/>
</Palette>
<Palette>
<Primary Name="Green"/>
<Other Name="Orange"/>
<Other Name="Yellow"/>
<Other Name="Violet"/>
</Palette>
</Palettes>
I want to have two combo boxes: One which displays the primary colors of each palette, and another which displays the “Other” colors of the palette selected in the first combo.
I would like to have this data binding done in the XAML file and not in the code-behind, if this is possible.
I have the following XAML file:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="80" Width="350">
<Window.Resources>
<XmlDataProvider x:Key="Palettes" Source="pack://siteoforigin:,,,/Palettes.xml" />
</Window.Resources>
<Grid>
<ComboBox x:Name="cbxPrimary"
DisplayMemberPath="Primary/@Name"
ItemsSource="{Binding Mode=OneWay, Source={StaticResource Palettes}, XPath=/Palettes/Palette}"
Margin="10,10,175,10"
SelectedIndex="0"/>
<ComboBox x:Name="cbxOther"
DisplayMemberPath="Other/@Name"
ItemsSource="{Binding ElementName=cbxPrimary, Mode=OneWay, Path=SelectedItem}"
Margin="175,10,10,10"
SelectedIndex="0"
SelectedValue="{Binding XPath=./Other/@Name}"
SelectedValuePath="./Other/@Name"/>
</Grid>
</Window>
However, this will show blank entries for the “Other” colors in the second combo box:
I cannot figure out whether I am missing something, or if this is coded improperly. How can this be corrected?
Answers & Comments...
As the name of DisplayMemberPath
implies it is a path to a member, not arbitrarily nested nodes or attributes. I would change the bindings as follows:
<ComboBox x:Name="cbxOther"
DataContext="{Binding ElementName=cbxPrimary, Path=SelectedItem}"
ItemsSource="{Binding XPath=./Other/@Name}"
Margin="175,10,10,10"
SelectedIndex="0"/>
Using SelectedValue
/Path
and DisplayMemberPath
only makes sense when the display should be different from the underlying value.
by: Answer by H.B. for How to bind two WPF combo boxes to a single XML file?
No comments:
Post a Comment
Send us your comment related to the topic mentioned on the blog