here is a question about a WPF application. I'm a self taught new programmer. I want to add a custom property in already existing image control in WPF.
Here is my XAML image control as
<Image x:Name="cardMPOne" HorizontalAlignment="Center" MouseDown="moveCard" Height="220" Margin="-300,20,0,0" VerticalAlignment="Top" Width="100"/>
I want to add some string or integer properties like CardType="Heart" CardColor="red" CardValue = "1" etc.
How this can be achieved...
Thanks in advance.
Your answer will be appreciated..
Related
I'm new in WPF and I start to use the ribbon:RibbonButton as follows:
<ribbon:RibbonButton x:Name="ServerCondition" Label="Server" FontFamily="Palatino Linotype" FontSize="12" BorderThickness="0" Height="50" CornerRadius="10" LargeImageSource="/Economy;component/Images/server_down.ico"/>
Now it comes to change the LargeImageSourse with another one dynamically from code behind.
First of all I don't know if that is posible.
And if it isn't posible... what control I may use to have the ability to change the icon?
If there is someone to assist me, I'll be thankful.
In your code behind, you can change it like so:
ServerCondition.LargeImageSource = new BitmapImage(new Uri("your uri"));
How to load image to WPF in runtime?
I am having a textblock element in WPF application that is bound to a combobox and I want the textbox text value to be copied to the clipboard when a button is pressed but i am unable to get the text value in the code behind as i am unable to use the textbox name itself to refer to its properties. This is a follow up to my previous question over here
Getting XML element from a Combobox item
the code is over there so donot want to extend the question these are the simple two lines of code
<TextBox Grid.Column="1"
Text="{Binding SelectedItem.Value, ElementName=QueryChooser}"
Grid.ColumnSpan="2" Grid.Row="1" Height="200" HorizontalAlignment="Left"
Name="textBlock1" VerticalAlignment="Top" Width="481" />
Firstly, I would recommend looking into the MVVM design pattern if you are serious about doing any WPF development. If you are using MVVM, then use an MVVM framework. It will make your life considerably easier.
Secondly, you need some kind of mechanism for invoking verbs on your data context (a view model in MVVM). WPF provides commanding, and MVVM frameworks provide other techniques and variations.
Once you have this mechanism, then you have the query text in your SelectedQuery property, so you can copy SelectedQuery.Value (a string) to the clipboard.
write CopyingCellClipboardContent event in your datagridTemplateColumn in xaml.
In code behind in this event write this,
if (dataGrid1.CurrentCell != null && dataGrid1.CurrentCell.Column == e.Column)
{ dataGrid1.SelectionUnit=Microsoft.Windows.Controls.DataGridSelectionUnit.Cell;
e.Content = ((System.Data.DataRowView)(dataGrid1.CurrentCell.Item)).Row.ItemArray[4].ToString();
}
else
e.Content = true;
Thanks..
[Edit #3] - to anyone reading this question: do not under any circumstance use the approach outlined in this question. It is a Coding Horror. I freely admit this, knowing that all programmers have worked themselves into a corner in the past, and (especially when learning a new technology) we all have been led astray by other, well-meaning developers on the interweb. Read the answer by Robert first, then read this question. Please.
[Edit #2b]
I apologize for the length of this question - there is a question in here (at the end!), but I wanted to make sure the source code was explicit. Anyway.
[Edit #2] - question title changed to more accurately reflect the... question.
[Edit] - I've updated some more of the history as to how I ended up at the design / code that I did here: Obligatory Blog Post. If it helps clarify the question below, feel free to read it...
Original question
The application I'm working on uses Prism and WPF, with a number of modules (currently 3), one of which hosts the application menu. Originally, the menu was static with hooks into CompositeCommand / DelegateCommands, which worked great for routing button presses to the appropriate presenter. Each MenuItem used a StackPanel in its header to display the content as a combination of an image and a text label - which was the look I was going for:
<Menu Height="48" Margin="5,0,5,0" Name="MainMenu" VerticalAlignment="Top" Background="Transparent">
<MenuItem Name="MenuFile" AutomationProperties.AutomationId="File">
<MenuItem.Header>
<StackPanel>
<Image Height="24" VerticalAlignment="Center" Source="../Resources/066.png"/>
<ContentPresenter Content="Main"/>
</StackPanel>
</MenuItem.Header>
<MenuItem AutomationProperties.AutomationId="FileExit" Command="{x:Static local:ToolBarCommands.FileExit}">
<MenuItem.Header>
<StackPanel>
<Image Height="24" VerticalAlignment="Center" Source="../Resources/002.png"/>
<ContentPresenter Content="Exit"/>
</StackPanel>
</MenuItem.Header>
</MenuItem>
</MenuItem>
<MenuItem Name="MenuHelp" AutomationProperties.AutomationId="Help" Command="{x:Static local:ToolBarCommands.Help}">
<MenuItem.Header>
<StackPanel>
<Image Height="24" VerticalAlignment="Center" Source="../Resources/152.png"/>
<ContentPresenter Content="Help"/>
</StackPanel>
</MenuItem.Header>
</MenuItem>
</Menu>
Unfortunately, the application has gotten a bit more complex and it is desireable to have other modules register themselves with the menu - hence, I've been looking at making the menu dynamic. The goal is to have other modules (through a service) be able to add commands to the menu at will - for example, Module A will add a menu item in the Toolbar module that calls a handler in Module A. There's a few excellent articles out there on this subject - the two I've looked at are Building a Databound WPF Menu Using a HierarchicalDataTemplate and WPF Sample Series - Databound HierarchicalDataTemplate Menu Sample. Following the advice in the article, I have managed to make a dynamically constructed menu with no obvious data binding problems - it can create a menu with items linked backed to my presentation model, reflecting the structure of an ObservableCollection in the presentation model
Currently, my XAML looks like the following:
<UserControl x:Class="Modules.ToolBar.Views.ToolBarView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:model="clr-namespace:Modules.ToolBar.PresentationModels"
xmlns:local="clr-namespace:Modules.ToolBar">
<UserControl.Resources>
<model:ToolBarPresentationModel x:Key="modelData" />
<HierarchicalDataTemplate DataType="{x:Type model:ToolbarObject}"
ItemsSource="{Binding Path=Children}">
<ContentPresenter Content="{Binding Path=Name}"
Loaded="ContentPresenter_Loaded"
RecognizesAccessKey="True"/>
</HierarchicalDataTemplate>
</UserControl.Resources>
<UserControl.DataContext>
<Binding Source="{StaticResource modelData}"/>
</UserControl.DataContext>
<Menu Height="48" Margin="5,0,5,0" Name="MainMenu" VerticalAlignment="Top" Background="Transparent"
ItemsSource="{Binding}">
</Menu>
</Grid>
</UserControl>
The code behind for the view does the heavy lifting in the ContentPresenter_Loaded method:
private void ContentPresenter_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
ContentPresenter presenter = sender as ContentPresenter;
if (sender != null)
{
DependencyObject parentObject = VisualTreeHelper.GetParent(presenter);
bool bContinue = true;
while (bContinue
|| parentObject == null)
{
if (parentObject is MenuItem)
bContinue = false;
else
parentObject = VisualTreeHelper.GetParent(parentObject);
}
var menuItem = parentObject as MenuItem;
if (menuItem != null)
{
ToolbarObject toolbarObject = menuItem.DataContext as ToolbarObject;
StackPanel panel = new StackPanel();
if (!String.IsNullOrEmpty(toolbarObject.ImageLocation))
{
Image image = new Image();
image.Height = 24;
image.VerticalAlignment = System.Windows.VerticalAlignment.Center;
Binding sourceBinding = new Binding("ImageLocation");
sourceBinding.Mode = BindingMode.TwoWay;
sourceBinding.Source = toolbarObject;
image.SetBinding(Image.SourceProperty, sourceBinding);
panel.Children.Add(image);
}
ContentPresenter contentPresenter = new ContentPresenter();
Binding contentBinding = new Binding("Name");
contentBinding.Mode = BindingMode.TwoWay;
contentBinding.Source = toolbarObject;
contentPresenter.SetBinding(ContentPresenter.ContentProperty, contentBinding);
panel.Children.Add(contentPresenter);
menuItem.Header = panel;
Binding commandBinding = new Binding("Command");
commandBinding.Mode = BindingMode.TwoWay;
commandBinding.Source = toolbarObject;
menuItem.SetBinding(MenuItem.CommandProperty, commandBinding);
}
}
}
As you can see, I'm attempting to recreate the StackPanel / Image / Name combination of the original menu, just doing so in the code behind. Attempting to do this has not worked out so well - while the menu objects are certainly being created, they don't "appear" as anything other than blank, clickable objects - the StackPanel, Image, Name, etc. aren't being rendered. Interestingly enough, it also is causing the original text in the ContentPresent in the HierarchicalDataTemplate to be erased.
The question then, is there a way to set a MenuItem's Header property in the Load event such that it will display on the UserControl properly? Is the fact that the items in the header are not being displayed indicative of a DataBinding problem? If so, what would be the proper way to bind the Header to a transient object (the StackPanel that was created in the load event handler)?
I'm open to changing anything in the code above - this is all sort of prototyping along, trying to figure out the best way to handle dynamic menu creation.
Thanks!
I'll confess that I haven't dug quite as deep into your example as maybe I should, but whenever I see code-behind that's searching the visual tree, I think, could this be handled more explicitly in a view model?
It seems to me in this case that you could come up with a pretty straightforward view model - an object exposing Text, Image, Command, and Children properties, for instance - and then create a simple data template that for presenting it as a MenuItem. Then anything that needs to alter the contents of your menus manipulates this model.
Edit:
Having looked at what you're up to in more detail, and the two examples you've linked to in your blog post, I am banging my head against the desk. Both of those developers appear to be under the misapprehension that the way to set properties on the menu items that are being generated by the template is to search through the visual tree in the ContentPresenter.Load event after they're created. Not so. That's is what the ItemContainerStyle is for.
If you use that, it's quite straightforward to create dynamic menus of the type you're describing. You need a MenuItemViewModel class that has INotifyPropertyChanged implemented and exposes these public properties:
string Text
Uri ImageSource
ICommand Command
ObservableCollection<MenuItemViewModel> Children
Using this:
<Menu DockPanel.Dock="Top" ItemsSource="{DynamicResource Menu}"/>
where the ItemsSource is an ObservableCollection<MenuItemViewModel>, and using this template:
<HierarchicalDataTemplate DataType="{x:Type local:MenuItemViewModel}"
ItemsSource="{Binding Path=Children}">
<HierarchicalDataTemplate.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Command"
Value="{Binding Command}" />
</Style>
</HierarchicalDataTemplate.ItemContainerStyle>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding ImageSource}" />
<Label Content="{Binding Text}" />
</StackPanel>
</HierarchicalDataTemplate>
the menus in the window exactly represent what's in the collection, and are dynamically updated as items are added and removed, both to the top-level items and to the descendants.
There's no clambering about in the visual tree, no manual creation of objects, no code-behind (other than in the view model, and in whatever populates the collection in the first place).
I've built a pretty thoroughly worked example of this; you can download the project here.
Another possible approach could be having the Menu be a region and agree on a convention so all views added to that region have a ViewModel with a property named MenuHeader. That way, the region adapter can simply get the menu header from the View's Data Context, and set it to the item when adding it.
Something similar is done in Prism with views added to a Tab Region. You can read more here.
I hope this provides some useful guidance.
Thanks,
Damian
I am trying, and failing, to create a list of labels and text boxes in WPF. I am a ASP.NET developer and the XAML experience is slightly overwhelming me at the moment... I have Apress' Pro WPF 3.0 book infront of me and finding it zero use...
At the end of my process I want users to complete some questions that will be dynamic to that user. I have an Array of objects, with properties for a "Question" and "Answer".
I want the "Question" to appear as the label.
I've been looking at ListView controls, but this just seems to give me an Excel style grid which I am not interested in.
In the ASP.NET world I'd use a GridView, with two columns, one with a Label, the other with a TextBox. On submitting the page I'd loop through the items in the grid view to pick out the values of the textboxes, and associate back to the correct object in the Array.
Could someone please direct, or show me what controls I should be using in WPF?
Extra info;
It's a desktop WPF application using .NET 4, Visual Studio 2010.
Cheers
Stu
There's absolutely no need to use a DataGrid for something as simple as this. Using a basic ItemsControl will do what you're looking for without the overhead of such a complex control. This approach is also very easy to customize by just changing the ItemTemplate.
<ItemsControl ItemsSource="{Binding QuestionsToAnswer}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding QuestionText}"/>
<TextBox Text="{Binding AnswerText}" Grid.Column="1"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I agree with Scott that DataGrid is probably the way to go. Here are some decent turotials to get you started:
http://www.c-sharpcorner.com/UploadFile/mahesh/WpfDGP109272009111405AM/WpfDGP1.aspx
http://www.wpftutorial.net/DataGrid.html
Hey guys, I've got what I think is an interesting question:
You all know and love the Skype chat interface: each message is enclosed in a bubble, with emoticons and link capabilities, as well as an avatar at the left.
What is the most ideal WPF component to house each message in, if I were creating a Skype-like interface?
I am using MVVM, so all my messages are stored in the ViewModel as an ObservableCollection.
I have had problems binding to a RichTextBox, and so I have investigated binding to a Listbox, where each list item is a message and each item is styled to have a Skypey border and avatar etc.
Any ideas?
The only suitable solution that I have found is using the flowdocumentreader and an ivalueconverter to convert an array of strings to a flowdocument. It actually works great once I made my own scripting language similar to bbcode.
This was the sample I learned from. http://michaelsync.net/2009/06/09/bindable-wpf-richtext-editor-with-xamlhtml-convertor
It was a little overkill for me so I ended up just making the ivalueconverter and a simple script language.
The solution i see is that you should use DataTemplate and Style. The idea is following: each text message represented by class object. Now when you bind your message inside template, you explicit tell how do you want your messages will look like.
It will better for you to create a usercontrol that will know how represent your messages.
Example that represent similar idea, but idea is the same:
<Window.Resources>
<DataTemplate DataType="{x:Type model:MessageModel}">
<ed:Callout AnchorPoint="0,1.5" Margin="10" CalloutStyle="RoundedRectangle" Content="{Binding Path=Text}" Fill="#FFF4F4F5" FontSize="14.667" HorizontalAlignment="Left" Height="100" Stroke="Black" VerticalAlignment="Top" Width="200" />
</DataTemplate>
</Window.Resources>
<Grid>
<ItemsControl ItemsSource="{Binding Path=MsgList}" />
</Grid>
For that example you need attach Microsoft.Expression.Drawing.sll which come aside with Blend 4.