access codebehind method from resource dictionary in WPF - wpf

I have following grid inside WPF XML file
<Grid Grid.RowSpan="2" >
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height = "Auto" />
</Grid.RowDefinitions >
<telerik:RadAutoCompleteBox TextSearchMode = "Contains" Grid.Column= "0" Grid.Row= "0" Name="cmbStyleNo" Margin= "5"
DisplayMemberPath="SAMPLE_ID" ItemsSource="{Binding Styles}"
SelectionMode= "Single" AutoCompleteMode= "Suggest" NoResultsContent= "No Matches" SelectionChanged= "val_SelectionChanged" />
</Grid >
above RadAutoCompleteBox SelectionChanged="val_SelectionChanged" code behind method exist in its code-behind file like follows
private void val_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
...
}
Then I have requirement populate above same grid in another window using resource dictionary. so I copied that grid to that ResourceDictionary like follows
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:samplePrjkt"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation">
<ToolBar x:Key="MyToolbar" Height="120">
<!--Template-->
<GroupBox Header="Template" Style="{StaticResource ToolbarGroup}" Margin="3">
<StackPanel Grid.Row="1" Orientation="Horizontal">
<StackPanel Orientation="Vertical" Margin="0,2,0,2">
<Grid Grid.RowSpan="2" >
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<telerik:RadAutoCompleteBox TextSearchMode="Contains" Grid.Column="0" Grid.Row="0" Name="cmbStyleNo" Margin="5"
DisplayMemberPath="SAMPLE_ID" ItemsSource="{Binding Styles}"
SelectionMode="Single" AutoCompleteMode="Suggest" NoResultsContent="No Matches" SelectionChanged="val_SelectionChanged"/>
</Grid>
</StackPanel>
</StackPanel>
</GroupBox>
</ToolBar>
</ResourceDictionary>
then once I compile this I'm getting following error
'ResourceDictionary' root element requires a x:Class attribute to
support event handlers in the XAML file. Either remove the event
handler for the SelectionChanged event, or add a x:Class attribute to
the root element.

You need to manually add a code-behind file for the ResourceDictionary and define the val_SelectionChanged event handler in this file.
Please refer to the following link for more information and an example of how to do this:
Is it possible to set code behind a resource dictionary in WPF for event handling?
You basically just create a new class and name it "Dictionary1.xaml.cs" where "Dictionary1" is the name of your resource dictionary XAML file and then you set the x:Class attribute in the XAML file:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication1.Dictionary1"
...

Related

Capturing name of StackPanel from Drop event

Within WPF I have the following XAML code:
<Page x:Class="com.MyCo.MyProj.Pages.Configuration.ManageLinkage.MasterLinkage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:com.MyCo.MyProj.Pages.Configuration.ManageLinkage"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="MasterLinkage">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TabControl TabStripPlacement="Top" Background="Transparent">
<TabItem Header="Import">
<ListBox Margin="0,5,0,0" Name="lbxImportItems" HorizontalAlignment="Left" VerticalAlignment="Top" Width="110" Background="Transparent"
PreviewMouseLeftButtonDown="lbxImportItems_PreviewMouseLeftButtonDown" >
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" Name="DBImport">
<Image Source="/Images/DBImport25px.png" VerticalAlignment="Center" HorizontalAlignment="Center"></Image>
<TextBlock Text="Database" Foreground="AntiqueWhite"/>
</StackPanel>
<StackPanel Orientation="Vertical" Name="CSVImport">
<Image Source="/Images/CSVImport25px.png" VerticalAlignment="Center" HorizontalAlignment="Center"></Image>
<TextBlock Text="CSV Import" Foreground="AntiqueWhite"/>
</StackPanel>
</ListBox>
</TabItem>
</TabControl>
<Canvas x:Name="cnvsLinkScreen" AllowDrop="True" Grid.Column="1" Background="Transparent" Drop="cnvsLinkScreen_Drop" DragOver="cnvsLinkScreen_DragOver" ></Canvas>
</Grid>
The code for capturing the event is here:
private void cnvsLinkScreen_Drop(object sender, DragEventArgs e)
{
Canvas parent = (Canvas)sender;
object data = e.Data.GetData(typeof(string));
StackPanel objIn = (StackPanel)e.Data;
...
}
The drag and drop work great, the event method created the image in the canvas. However, I want to capture the Name="" from the StackPanels which are dropped.
I found the Name buried super deep in the "DragEventArgs e" object. I was think that there should be a way to cast the object (or the object within that object) as a StackPanel to easily work with it. The above code does not convert the StackPanel object( it's not at the root or the child object; I tried both) so it exceptions on "StackPanel objIn = (StackPanel)e.data;"
How do I either translate the incoming object to a StackPanel or how do I access the Name attribute from the Stackpanel?
I got it. I was close with the translation. To translate / typecast the object to what you are working with I needed to use the following line:
StackPanel objIn = (StackPanel)(e.Data.GetData(typeof(StackPanel)));
Which is slightly different than above.

How to add controls dynamically to a UserControl through user's XAML, 4.0

I want to create a user control that contains a Image and a Conainer that will allow the user to add his/her own controls to the user control dynamically in XAML. I am using VS 2010, .NET 4.0
I have created following code.
UserController.xaml
<Grid DockPanel.Dock="bottom">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Height="Auto" Grid.Row="0" Grid.Column="0">
<Image />
</StackPanel>
<Grid>
<ContentControl Content="{Binding Innercontent}" />
</Grid>
</Grid>
ModeViewCode, Innercontent is an DependencyProperty property
public static DependencyProperty InnerContentProperty = DependencyProperty.Register("InnerContent", typeof(UIElement), typeof(Footer))
public UIElement InnerContent
{
get { return (UIElement)GetValue(InnerContentProperty); }
set { SetValue(InnerContentProperty, value); }
}
Created a DataTemplate which consumes the usercontrol.
<users:Footer HorizontalAlignment="Stretch" VerticalAlignment="Bottom">
<users:Footer.InnerContent>
<StackPanel Orientation="Horizontal" x:Name="tst">
<commoncontrols:Button />
</StackPanel>
</users:Footer.InnerContent>
</users:Footer>
when code is complied it gives me following error message.
Error 275 Unknown build error, 'Index (zero based) must be greater than or equal to zero and less than the size of the argument list. Line 2582 Position 23.' at this line (users:Footer.InnerContent).
Got help from following psot Help
Any help will be appreciated.

WPF share resourcedictionaries among controls

I have 2 dictionaries merged in my WPF app (base dict merged with skin dict).
It works very fine on the MainWindow, but when I added a new WPF Window, it seems unable to access the StaticResource.
This is the code of the new Window:
<Window x:Class="Sc2ReplayMonkey.PleaseWaitWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
xmlns:local="clr-namespace:Sc2ReplayMonkey"
Title="PleaseWaitWindow" Height="300" Width="300">
<Grid Style="{StaticResource WindowBackground}">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Style="{StaticResource WindowTextelement}" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">
Please wait while the replays
</TextBlock>
<TextBlock Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center">
are parsed and serialized
</TextBlock>
</Grid>
</Window>
I get the error "Cannot find the resource named "WindowBackground".
It is defined in the skin dict as:
<Style x:Key="WindowBackground" TargetType="{x:Type Grid}">
<Setter Property="Background" Value="Black" />
</Style>
What did I miss?
I think you need to add
Resources.MergedDictionaries.Add(resources);
in you App.cs class once f.e in Initialize() method. Then your dictionary will be accessible from any windows.
This solved the problem, I simply added a line in PleaseWaitWindow's constructor: Resources = main.Resources; main being the MainWindow

How to add a WPF grid control from its XAML string at runtime?

Let's say we have a grid XAML like below - eg. a generated string returned from a method.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width='*' />
<ColumnDefinition Width='*' />
</Grid.ColumnDefinitions>
<TextBlock Text='id' Grid.Column='0'/>
<Rectangle Fill='Black' Grid.Column='1' />
</Grid>
What I want to do is to create such a grid and added to a stackpanel at run time, codes similar as below.
XmlReader xr = XmlReader.Create(input: new StringReader(g.xaml));
var control = XamlReader.Load(xr) as Grid;
this.stackPanel.Children.Add(control);
The form I use is:
<Window x:Class='AllRibbonBrushes.MainWindow'
xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
Title='MainWindow' Height='223' Width='533'
Loaded='Window_Loaded'>
<ScrollViewer>
<StackPanel Name="stackPanel">
<!--The runtime grid need to be added here-->
</StackPanel>
</ScrollViewer>
</Window>
But I get the error Cannot create unknow type 'Grid'. I succeed doing this by adding a button/a textblock but failed to add a grid with nested controls.
If you know how to do so, please share. All helps are welcome and very much appreciated!
Add xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' to the first Grid element in the xaml you would like load. This declares the wpf namespace the default namespace in your xaml. XamlReader.Load can then find out what kind of control is.
<Grid xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
<Grid.ColumnDefinitions>
<ColumnDefinition Width='*' />
<ColumnDefinition Width='*' />
</Grid.ColumnDefinitions>
<TextBlock Text='id' Grid.Column='0'/>
<Rectangle Fill='Black' Grid.Column='1' />
</Grid>

WPF Data Binding - Data Template is not Getting Values

I have the following DataTemplate:
<DataTemplate DataType="{x:Type Client:WorkItem}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>
<Label Name="lblIDText" Margin="2">WI ID:</Label>
<Label Name="lblID" Margin="2" Grid.Column="1"
Target="{Binding Id}"></Label>
<Label Name="lblTitleText" Grid.Row="1" Margin="2">WI Title:</Label>
<Label Name="lblTitle" Margin="2" Grid.Row="2" Grid.ColumnSpan="2"
Target="{Binding Title}"></Label>
</Grid>
</DataTemplate>
in my <Window.Resources> section. It is meant to show the Id and Title of a WorkItem object (from namespace Microsoft.TeamFoundation.WorkItemTracking.Client.)
I try to put this in a TabItem in a TabControl and it only shows the static text. (The WorkItem ID and title do not show, but the static text in my template does.)
Clearly the template is being fired, but the binding is not working and I can't seem to see why.
Here is my C# that calls it:
private void PickWorkItem_Click(object sender, RoutedEventArgs e)
{
int Id = int.Parse(((Button) e.OriginalSource).Tag.ToString());
_mediator.PickedWorkItem = GetWorkItemInQueryResultListByID(Id);
tabAddLinks.DataContext = _mediator.PickedWorkItem;
tabAddLinks.Content = _mediator.PickedWorkItem;
}
I tried it with DataContext in and out and it works the same. When I debug, the value for _mediator.PickedWorkItem is set correctly (Id and Title are both fine).
Any ideas on how to fix this would be appreciated.
You're binding the Label's Target property, when you actually want to be binding it's Content property:
<Label Content="{Binding Id}"/>
Also, consider using a TextBlock instead of a Label if you don't need the extra functionality a Label provides:
<TextBlock Text="{Binding Id}"/>
You are binding Label.Target. Target is the UIElement being labelled. You need to bind Label.Content, or change it to a TextBlock and bind TextBlock.Text.
(My guess would be that you were trying to bind a non-existent Label.Text property and Intellisense helpfully chose Target for you instead...!)
I'm pretty new to WPF, so excuse me if I'm off base, but don't you need to set the Content property of the label, not the Target?

Resources