i have some UserControls that are shown fine in designer, but i can't make any changes to the design-time example content from the constructor. It seems like it is not executed at all.
XAML:
<UserControl x:Class="Example.Test"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<TextBlock Name="testx" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
</Grid>
Code:
using System.ComponentModel;
using System.Windows.Controls;
namespace Example
{
/// <summary>
/// Interaction logic for Test.xaml
/// </summary>
public partial class Test : UserControl
{
public Test()
{
InitializeComponent();
if (DesignerProperties.GetIsInDesignMode(this))
testx.Text = " IN DESIGN!";
}
}
}
I've tried many options, but still can't get it how to display design-time data in WPF designer :( Different context binding also shows nothing...
PS: Tried clean VS2012 and VS2013 projects on Win8. NOTHING WORKS! :( I don't know what to do, haven't found anything similar on the net... Is it sufficient to just add design check in constructor and set existent control text? It should work, right?
K, the short answer is: You're on the right path.
The long one is: It's a bit more complicated than that.
Your example will "kinda" work, as in, if you'll put an else testx.Text = RUNTIME; after your if, like that:
if (DesignerProperties.GetIsInDesignMode(this))
testx.Text= " IN DESIGN!";
else
testx.Text= " Runtime";
you'll see what you want on runtime, but you're design time will stay empty.
For the Design time, you also need to set the context if I'm not mistaken.
If you're using any of the MVVM framework out there, you kinda get this functionality for "free". As in, you'll have a "in design time" property and you can set whatever data you want for the design. The catch is that you need to have an empty constructor if my memory serves me right.
You'll also use bindings, and not set the text property directly.
I remember that the default WPF and binding for design time was lacking a bit last time I tried to do something like that in "vanilla" wpf (as in, no MVVM, no bindings), but I believe that with a bit of a hack it's achievable. Again, can't remember it from the top of my head.
Related
UPDATE * My error had to do with the computer I was using and not being part of a FIPS validated algorithm. That error only appeared after I closed Visual Studio and tried to compile the default blank WPF form. I did the exact same thing on a personal computer and it compiled as expected. *
I'm familiar with creating windows form using C#. I looked into methods to change the look of my forms, similar to using skins, and was told that it would be easier if I I used WPF....ok.
In an effort to become familiar with WPF, I picked up a book, "MASTERING_WINDOWS_PRESENTATION_FOUNDATION" and it was slow moving with a discussion on MVVM and data binding (new topics to me). I felt the I could learn the difference between WPF and Windows Forms much faster if I first tried to create a simple WPF application. Then, as I read, I could see how something done in a very familiar way using Windows Forms, is done using WPF.
Unfortunately, I'm stuck right out the box!
Using VS2017, I created a new WPF App (.NET Framework) I then added a text box and a button. I created a name for both as this does not appear to be automatically created like with Windows Forms. I then double click on the button and a method block is created in the MainWindow.xaml.cs file. I proceed to add text to the textbox
(txtbox_1.Text="Hello;").
I noticed a few things:
1.) The InitializeComponent(); call in the MainWindow() method is underlined and corresponds to the CS0103 Error
2.) Intellisense did not recognize the textbox. I typed out the full name and it created an error when I was done. (Same CS0103 Error)
I looked through stackoverflow but found articles about Xamarin. I've heard of this as a way to write code for Android but do not know how it relates to what I'm trying to do.
What am I missing?
Here is my XAML file:
<Window x:Class="WpfApp4.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:WpfApp4"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Button x:Name="btn_browse" Content="Button" HorizontalAlignment="Left" Margin="524,91,0,0" VerticalAlignment="Top" Width="75"/>
<TextBlock x:Name="txtbox_1" HorizontalAlignment="Left" Margin="134,93,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Height="20" Width="363"/>
</Grid>
</Window>
And here is my MainWindow.xaml.cs file:
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp4
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public void SimpleMethod()
{
txtbox_1.Text = "Hello";
}
}
}
That InitializeComponent(); line is hugely significant since it is that instruction makes your xaml turn into UI.
If it's underlined then your partial class for code behind isn't matching up with the xaml.
You will have something like
Either that or you're missing some fundamental references should have been added when you started your project.
I suggest you just bin your sln though.
Just delete it and start again.
Create a new wpf project.
Hit f5.
If it crashes and burns your VS install is broken.
Anyone and everyone will tell you to learn MVVM. And you should.
https://social.technet.microsoft.com/wiki/contents/articles/31915.wpf-mvvm-step-by-step-1.aspx?Redirected=true
https://social.technet.microsoft.com/wiki/contents/articles/32164.wpf-mvvm-step-by-step-2.aspx?Redirected=true
That means that your MainWindow class actually does not inherit from System.Windows.Window class.
I don't see a reference to System.Windows in your class. This is the namespace, where the WPF Window basic class is defined. So your Window base class can reference a Window class from some other namespace, and, that's why it has no InitializeComponents() method and can not reference the property from XAML. Try first adding this using directive to code behind class. If that doesn't do the task, check if your project has a reference to System.Windows. If there is no System.Windows in your reference manager (this could be if your project is set to compile in .NET 4.0) add references to PresentationFramework, PresentationCore and WindowsBase.
The error had to do with the work computer I was using ... something to do with FIPS. You should be able to create a new WPF project and compile the blank form without error. I did the exact same thing on a personal computer and it compiled as expected. I was also able to reproduce a WinForms project as a WPF using code behind without error. Implementation using MVVM took a significant amount of time since the concept of view models was new to me but, in the end, it's not bad.
I tried to bind the visibility of a few buttons to some booleans in a viewmodel and make it work in design-time. I did this several times and never had a problem, but now it does not work and I don't have a clue why. Note that everything works
fine when I run the application.
I extracted the essence into a separate app and it still doesn't work!
My XAML:
<Window x:Class="BindingTest.MainWindow"
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:bindingTest="clr-namespace:BindingTest"
Title="MainWindow" Height="350" Width="525"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance bindingTest:TestViewModel, d:IsDesignTimeCreatable=true}">
<Grid>
<Grid.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
</Grid.Resources>
<StackPanel>
<Button Visibility="{Binding IsButton1Visible, Converter={StaticResource BoolToVis}}">Hallo 1</Button>
<Button Visibility="{Binding Button2Visibility}">Hallo 2</Button>
<Button>Hallo 3</Button>
</StackPanel>
</Grid>
</Window>
My ViewModel:
public class TestViewModel
{
public bool IsButton1Visible
{
get { return true; }
}
public Visibility Button2Visibility
{
get { return Visibility.Hidden; }
}
}
To make it work in the real app, i added to the constructor of the XAML:
DataContext = new TestViewModel();
This is all pretty simple, but why is it not working in the designer?? I always got this to work in the past and now I tried for hours... It's not the only binding not working, but why is not even this working??
Expected Result:
Button1 visible
Button2 hidden
Button3 visible
Result in the designer:
Button1 collapsed
Button2 visible
Button3 visible
UPDATE: The problem with design-time DataContext bindings not working is due to mistakenly using the d: namespace prefix for the IsDesignTimeCreatable property.
So, change
d:IsDesignTimeCreatable=True
to
IsDesignTimeCreatable=True
and everything should be fine. (My bug report filed with MS will be updated with this information as well.)
As this problem with the design-time DataContext bindings not working was consistently reproducable in VS2015 as well as VS2013 when IsDesignTimeCreatable is prefixed with the d: namespace (see comments below the question), i decided to file a bug report with Microsoft: Issue #1651633 "WPF designer: Designtime DataContext bindings broken?".
Lets see how Microsofts will follow-up with regard to this issue. It should be addressed, since such an issue can catch a developer off-guard and make him reinstall Visual Studio for no benefit... ;)
If anything is OK with the code, there could be an other tricky problem:
In the Designer of Visual Studio a new button was introduced in 2019, which enables / disables the preview of design data.
It's a very tiny button on botton left of the designer window. It's tooltip is "Enable Project Code".
Click this important toggle button to see the design data. (But be aware that you don't disable it, if it's already enabled.)
I am working on my first project in MVVM and I've chosen to use the MVVM Light Toolkit. I have a GameViewModel that handles business on the main screen of my game. I need to find out how to open a new window (AdventurerView) with an instance of Adventurer as a parameter when a command is executed, have it bound to AdventurerViewModel, and display and return data. Instances of this window will be opened and closed frequently. I have been stuck on this for a couple of days now and it's driving me crazy. I would like to learn how to do this in an MVVM-friendly way, preferably with the tools provided by MVVM Light or pure XAML.
I've tried using MVVM Light's ViewModelLocator but since AdventurerView is a window it won't work; it says "Can't put a Window in a Style", though the program still compiles and runs. Could there be something I could change to make that work? Or is there another way to bind them in XAML? Or another approach entirely? I would really love to be able to move on from this. I have also tried using MVVM Light's messenger to no avail (which still doesn't tackle the View/ViewModel issue).
I just need to be able to create a window that is bound to AdventurerViewModel and display/return the appropriate data.
AdventurerView.xaml is in its default state at the moment, but I feel that if I could bind the appropriate data that might help (DataContext).
AdventurerViewModel is pretty bare-bones as well
class AdventurerViewModel : ViewModelBase
{
#region Members
private Adventurer _adv;
#endregion
#region Properties
public Adventurer Adv
{
get { return _adv; }
set { _adv = value; }
}
#endregion
#region Construction
public AdventurerViewModel(Adventurer adv)
{
this._adv = adv;
}
#endregion
}
App.xaml with the non-working DataTemplate at the bottom:
<Application StartupUri="MainWindow.xaml"
xmlns:views="clr-namespace:AoW.Views"
xmlns:vm="clr-namespace:AoW.ViewModels"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="AoW.App"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Application.Resources>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
<DataTemplate DataType="{x:Type vm:GameViewModel}">
<views:GameView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:TitleViewModel}">
<views:TitleView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:AdventurerViewModel}">
<views:AdventurerView />
</DataTemplate>
</Application.Resources>
</Application>
The command in GameViewModel that will hopefully make this all happen (the messagebox just confirms that the command is firing):
private void ExecuteShowAdvCommand(Adventurer adv)
{
System.Windows.MessageBox.Show(adv.Name);
}
I don't really know what else to include.
Ok I put together a demo that should make this hopefully easier for you Download Link
Functionality:
3 Windows in Total (MainWindow, ModalWindow, NonModalWindow)
MainWindow has a TextBox you can type whatever you want into.
2 buttons on the top will open the Modal / NonModal Window accordingly
Each window when opened will display the message that was in MainWindow's TextBox in a TextBlock inside them.
In each window you can tick a CheckBox to update the value in result's textblock in MainWindow (For the Modal Window this will kick in when modal window is closed. For NonModal changes can be seen asap)
That's it for functionality,
Concepts:
Registering Multiple VM's with the SimpleIoC and using GetInstance(...) to request them out.
Messenger class usage with a custom message type OpenWindowMessage
Opening Modal / Non Modal Windows from a parent VM staying true to the MVVM principles
Passing data between windows(just shown in NonModal)
Important Note:
- The method used in this example to set the non DP DialogResult from the modal window is not MVVM friendly cos it uses code-behind to set the DialogResult property on a Window.Closing event which should be avoided(If needing to be "testable"). My preferred approach is a bit long and is very well documented HERE(Mixture of question and answer). Hence why I ignored it for the sake of this sample.
Follow up to Viv, I modified the sample to include an example of opening the window without using a code behind.
Sample project is here.
I'm utilizing the ViewModelLocator singleton with a static method that news up the viewmodel and window and Data Context instead of the code behind.
Blog Post with Details.
Let me know which method is preferable. I dislike using code behind, but there could be pro's and con's I'm missing.
I've been merrily using the DesignData in Windows Phone apps, and I was hoping to use it to help visualise designs in a Metro style app in VS2012/Blend for VS.
I've tried the hopefully obvious:
<common:LayoutAwarePage
x:Name="pageRoot"
x:Class="MyRootNamespace.Views.EventView"
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
IsTabStop="false"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyRootNamespace.Views"
xmlns:common="using:MyRootNamespace.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:bm="using:Bing.Maps"
d:DataContext="{d:DesignData Source=../SampleData/SpecialEventSampleData.xaml}"
mc:Ignorable="d">
With the SpecialEventSampleData.xaml looking loosely like:
<local:SpecialEvent
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyRootNamespace.ViewModels"
EventName="Foo Fighters"
Description="This exclusive April Fools Gig will see Dave Grohl and the rest of the Foo Fighters rock out at this exclusive made up gig"
VenueName="Village Hall"
/>
The class to which it refers has a public, parameterless constructor, but Visual Studio is giving an error:
Error Cannot create an instance of "SpecialEvent". C:...\MyRootNamespace.Windows\SampleData\SpecialEventSampleData.xaml
In addition, I was expecting to have to set the build action to "DesignData", or similar, but this doesn't appear to be an option in Visual Studio 2012?
What do I need to do to be able to get design time data to work in VS2012/Blend?
Is SpecialEvent your ViewModel? If so, can you do something like this in your XAML (directly after your common:LayoutAwarePage opening declaration)?
<d:Page.DataContext>
<local:SpecialEvent>
</d:Page.DataContext>
And then remove this line from your common:LayoutAwarePage:
d:DataContext="{d:DesignData Source=../SampleData/SpecialEventSampleData.xaml}"
I have code similar to this that is working.
In Windows Phone (I believe) the path to the sample data file is relative to the application root. In Windows 8, the path to the sample data file is relative to the page xaml file you want to use it in.
In your sample above, the page.xaml file would need to be in a sub-folder of the project but in a different folder than SampleData.
Windows 8 sample data does not automatically create collection instances for you. So, if you have sample data like this:
<Event>
<Attendees>
<Attendee Name="Joe" />
</Attendees>
</Event>
you would need to make sure that the backing field for the Attendees property is set to a new collection instance when you define the variable. If you are using automatic properties (Attendees { get; set; } syntax) you will need to set the property to a new collection instance in the constructor before items can be added in xaml.
Finaly, Windows 8 xaml cannot handle generic types. So, if your Attendees property is of type Collection<Attendee> you will not be able to create an instance of it in xaml.
You can always make a simple class called AttendeeCollection that inherits from Collection<Attendee> and create instances of that in your xaml instead.
Hope that helps.
Try full path to the xaml file instead of relative.
This is a touch obscure, but it boils down to the implementation I had of INotifyPropertyChanged on my View-Model.
In my Windows Phone code, I have to go to a small amount of effort to ensure that the events raised by background worker threads pop out on the UI thread:
protected delegate void OnUIThreadDelegate();
protected void OnUIThread(OnUIThreadDelegate onUIThreadDelegate)
{
if (Deployment.Current.Dispatcher.CheckAccess())
{
onUIThreadDelegate();
}
else
{
Deployment.Current.Dispatcher.BeginInvoke(onUIThreadDelegate);
}
}
This was then used:
protected override void OnPropertyChanged(PropertyChangedEventArgs e)
{
OnUIThread(() =>
{
base.OnPropertyChanged(e);
});
}
It appears that when porting that code, I was not checking the result of CoreWindow.GetForCurrentThread() which was causing an exception to fire deep in the darkest depths of the code, as the designer was setting the properties on my type, and I was trying to raise the events and dying horribly instead. My bad.
I think I'm asking for a lecture on the proper application of WPF here but I'm going to take my chances since I'm at my wit's end. I think this is probably largely a result of my lethargy in fully embracing WPF templates and styles so I'm happy to listen to any such lectures.
I'm writing a sort of audio editor / event orchestrator. I've got a track editor that I'm fairly happy with. However, I built it largely out of custom controls (I know, this is probably a WPF sin). In keeping with that theme, I want to make a standard header for the tracks but I want the individual track "types" to be able to define what goes in that header. I thought a control that defines a sort of "grip" on the edge and then allowed the implementer to "fill in" the substance would work well. However, I have no idea how to do this in WPF without using styles and even if I end up using styles, I would like to understand this.
This probably comes down to wanting a sort of exemplar implementation of a simple ContentControl control (e.g. a button) and not being able to find one (other than AvalonDock, which ultimately uses - correctly i'm sure - templates for this). In my head, the xaml looks something like this:
<ContentControl x:Class="TestArea.CustomContentControl2"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Hello"/>
<ContentPresenter Grid.Column="1"/>
</Grid>
But of course, that doesn't work. I'm fairly sure I could pull the same thing off by playing tricks with overloads behind the scenes, but it would be nice if I could do something like this. Do I really have to put all my terrible, procedural ways behind me and use these styles you speak of? If so, can someone at least tell me what that button looks like down in the framework?
Here is a complete example of deriving from ContentControl to accomplish what you want: Creating Customized UserControls (Deriving from ContentControl) in WPF 4
Pete's ContentPresenter is doing the same thing as it does in your example.
Using styles allows you to seperate functionality of a control with representation of a control; such as the Button.
Think as a control at the start as nothing more then functionality. A simple class containing predefined events, properties, etc... Once that control takes on the job of becoming part of a visual tree it now needs a visual identity. It didn't need one previously; however now it does. Defining a default style allows that control to now have a visual representation which it did not need prior as it was not living within the visual tree.
Ignoring styles would be like ignoring CSS when making use of HTML.