I created a UI using XAML, in windows phone 7. I want to know if this code exists as C# code in some file and if it is so, where is the designer code, generated by the xaml?
If you want to create StackPanel programmatically, you can do it by "mimicking" the XAML version.
For example, the following XAML:
<StackPanel Foreground="White"
Margin="12,0,0,0">
</StackPanel>
can be created with the following C# code:
var stackPanel = new StackPanel();
stackPanel.Foreground = new SolidColorBrush("White");
stackPanel.Margin = new Thickness(12,0,0,0);
Without knowing what your StackPanel looks like, I cannot offer you any tipss.
I must wonder why you want to do that? XAML is generally far better to design than doing it in via code. Not to mention it is cleaner and is adaptable to MVVM which is the best solution for your application.
If you offer some more details, I can offer precise advice.
When you create code in XAML this code in C# doesn't exist in any file in your project.
The XAML code is changed to object in compilation process.
Here You have great article about this process:
Article
You can create GUI in code behind using objects like this:
var stackPanel = new StackPanel();
Related
I'm using XAML Islands to make my app and I want to use Windows 10 styling in my WPF app like here. For example <TextBlock Text="Header" Style="{StaticResource HeaderTextBlockStyle}"/> would result in:
But this doesn't work in WPF (It does work in UWP without any modifications), my understanding is that XAML Islands should make it possible. When I try to simply add the code above to my xaml file I get the exception
Cannot find resource named 'HeaderTextBlockStyle'. Resource names are case sensitive.
I get the same exception if I add Style="{StaticResource HeaderTextBlockStyle}" to a <xamlhost:WindowsXamlHost> element.
So I tried to add the controls with code so I added this WindowsXamlHost control as a stackpanel:
<xamlhost:WindowsXamlHost InitialTypeName="Windows.UI.Xaml.Controls.StackPanel" ChildChanged="WindowsXamlHost_ChildChanged"/>
And added this method (an event handler that is ran when the control is made. Learned it from this) that handles adding additional controls (a TextBlock) to the StackPanel:
private void WindowsXamlHost_ChildChanged(object sender, EventArgs e)
{
// Get the host control
WindowsXamlHost host = (WindowsXamlHost)sender;
// Get the StackPanel in the host
Windows.UI.Xaml.Controls.StackPanel sp = (Windows.UI.Xaml.Controls.StackPanel)host.Child;
// Make a TextBlock to add to the StackPanel
Windows.UI.Xaml.Controls.TextBlock textBlock = new Windows.UI.Xaml.Controls.TextBlock();
// Set the text of the TextBlock
textBlock.Text = "LockCursorInMonitor";
// Get the style resources, cast them to the appropriate type for XAML Islands and add them to the TextBlock
textBlock.Style = (Windows.UI.Xaml.Style)Application.Current.Resources["HeaderTextBlockStyle"];
// Another way to get resources but this doesn't work too.
//textBlock.Style = (Windows.UI.Xaml.Style)this.FindResource("HeaderTextBlockStyle");
// Add the TextBlock to the stackpanel
sp.Children.Add(textBlock);
}
The Application.Current.Resources["HeaderTextBlockStyle"] way does nothing and doesn't throw an exception.
The this.FindResource("HeaderTextBlockStyle") way throws the next exception:
System.Windows.ResourceReferenceKeyNotFoundException: ''HeaderTextBlockStyle' resource not found.'
So how can I get these style resources in my WPF app?
One way to achieve this is to use the package ModernWPF but then you lose all the benefits of XAML Islands (if there are any. Everything I needed from XAML Islands is in ModernWPF and is easier to implement).
After installing and setting ModernWPF up you can simply use the <TextBlock Text="Header" Style="{StaticResource HeaderTextBlockStyle}"/> way and it just works.
When a named XAML element is used in a WPF application, it can be accessed from anywhere. For example:
<Grid>
<Grid>
<TreeViewItem Name="itemScreen" />
The element itemScreen will be directly accessible in MainWindow(), although it is several levels deep in the XAML hierarchy.
How does WPF enable this to work in C#?
There's a mechanism called NameScope.
https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/wpf-xaml-namescopes
Simple markup you put in a window which has no templating or styling will all have the one namescope.
If you dig through that link it will explain about styles and templates in more detail. Essentially, they have their own namescope.
This is probably as far as you want to go with an explanation at this stage but there are a couple of oddities like when you "inherit" a style using basedon.
I wouldn't worry about them just yet but throw it to the back of your mind for later.
ps
That control is a private member of your window and the name doesn't have to be unique across the entire application.
I am new to XAML and C#
I have an icon created already in a project and and I have to use this icon whenever I select one of the option from the dropdown menu.
I made a stackpanel in XAML file
<StackPanel Name="stackPanelforIcon">
</StackPanel>
In the code behind file I have different cases for the dropdown menu.
case IconOnSelect:
?????? = IconList.NewIcon;
This NewIcon is the one already created and I am using the source also for this
using IconProject.Iconlists;
On writing IconList.NewIcon I am not getting any error, it is referenced correctly.
What should I write at ?????? to reference it. Is there any other way apart from using stackPanel to include an icon
A StackPanel cannot show an icon on it's own. You need a control for it, for example an Image.
<StackPanel Name="stackPanelforIcon">
<Image x:Name=theImage" />
</StackPanel>
Then you can use your Icon in your code behind like this:
this.theImage.Source = IconList.NewIcon;
You may need to convert your value, you never said what type it actually is.
Please note that using code-behind is not the preferred way with WPF. Using MVVM is way easier and more natural working with WPF, using code-behind you will fight WPF all the way. Using MVVM, this could be:
<StackPanel Name="stackPanelforIcon">
<Image Source="{Binding CurrentImage}" />
</StackPanel>
with your ViewModel having a property called CurrentImage that you would set when you want to change it. Don't forget to implement INotifyPropertyChanged for the changes to take effect though.
Question
Basically I would like to do the following but it seems that I cannot:
UserControl myControl = new UserControl();
DataTemplate template = new DataTemplate(myControl);
The question: Is it possible to construct a DataTemplate from UserControl instance? If not, are there any other possible solutions?
Real problem
I'm working on a project where majority of UI views are simple static Word-like documents (e.g some text fields and maybe some images, nothing too fancy). Because most of persons working on this project are not coders we have designed very simple in-house markup language for UI generation. An example of markup of simple view is following:
First name: [Person.FirstName]
Last name: [Person.LastName]
Address: [Person.Address.Street], [Person.Address.City]
Now these templates are loaded at runtime and usercontrols are created based on them. In this case one usercontrol would be created and it would contain simply couple of stack panels and text blocks so that resulting control would look a bit like text document. XAML equivalent would be something like:
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="First name: "/>
<TextBlock Text={Binding Person.FirstName}
</StackPanel>
<StackPanel>
...
</StackPanel>
...
</StackPanel>
Then, I started to implement support for lists but couldn't think of a way how to do that. In theory it is simple and I came up with following syntax (+ XAML equivalent):
[List Customers]
First name: [Person.FirstName]
Last name: [Person.LastName]
Address: [Person.Address.Street], [Person.Address.City]
[EndList]
->
<StackPanel>
<ItemsControl ItemsSource="{Binding Customers}">
<ItemsControl.ItemTemplate>
<DataTemplate>
[Insert code from previous XAML example here]
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
But I can't do that because it seems that I cannot construct DataTemplate directly from UserControl instance. There would be no problems if my UserControls were types, but they are not.
One possible solution is that I could bind ItemsControl.Items directly to list of UserControls (instead of binding to ItemsSource and ItemTemplate) but this is sub-optimal in our case for couple of reasons. I would be willing to try some other solutions first!
Update
For clarification: all I have is plain instance of UserControl class which contains the content I need. E.g.
UserControl control = new UserControl();
var panel = new StackPanel();
panel.Children.Add(...);
panel.Children.Add(...);
control.Content = panel;
// How to use that control as ItemTemplate for ItemsControl?
// It seems that it is not possible directly but I want to
// know what my options are.
I don't have class for it because I'm constructing it at run-time and I don't want to create new type dynamically by emiting IL code because it is way too painful.
Creating a datatemplate from Code behind goes like this:
FrameworkElementFactory factory = new FrameworkElementFactory(MyUserControl.GetType());
DataTemplate dt = new DataTemplate();
dt.VisualTree = factory;
yourItemsControlInstance.ItemTemplate = dt;
A datatemplate is a definition of controls to be built at runtime, that is way this construction with a ElementFactory. You do not want the same instance of the UserControl for every item in your ItemsControl.
Ah I understand your problem now. I don't think there is an easy way (one or two lines of code) to create a datatemplate from a UserControl instance.
But to solve your problem I see two directions:
At the point where an usercontrol is created, create a datatemplate instead and use that. It will be cumbersome, with nested FrameworkElementFactories. I have never done that, and the MSDN documentation says that you may encounter some limitations you cannnot do compared to datatemplates in Xaml. But if it is simple it must be doable. There used to be a codeproject article by Sacha Barber you could use as a guidance (if needed).
You pack the creation of the UserControl in a method called private UserControl createMyUserControl(){}
And do something like this:
ItemsControl itemsControl = new ItemsControl();
foreach (var customer in Customers)
{
var usercontrol = createMyUserControl(...);
usercontrol.DataContext = customer;
itemsControl.Items.Add(usercontrol);
}
Second option is less elegant in my opinion, so I would check out the option 1 first.
WPF: How to create Styles in code/and magical Content (see section at the end for extensive sample of a DataTemplate in Code behind)
I think you can replace UserControl with the ContentControl.
Just set the content of the ContentControl to the desired template and use it as ItemTemplate for the ItemsControl.
So I'm trying to understand some code we have on a project that is in C#/WPF. I'm pretty new and just learning whatever I can. Looking at one of the .xaml, we have a DataTemplate that lays out where things go for our app. I want to add some events to it, but there is no code behind the .xaml since it is not a class like other .xamls in our project. The DataType of the DataTemplate points to a ViewModel class, but this class does not see my objects in the DataTemplate. Any thoughts? Thanks.
To add rich event-based behavior to elements created through XAML, you need to utilize attached behaviors.
In addition to the attached behaviors John mentioned above, if you are using MVVM, you can utilize the commanding architecture in WPF. Check out ICommand and implementing those on your ViewModel. You will have something like this:
Command="{Binding YourCommandName}"