Add additional content to the custom user Control WPF - c#

I have a custom user control which contains ToolBar with buttons. I want these buttons and toolbar to be the base content of the control and assign it to different views. But for some views, in some cases, I need to add additional tools to the toolbar, or additional toolbar itself at the end of the already existing ones.
I tried control template and dependency property binding. In control template case I must move my already existing buttons from Content to template and that makes my buttons inaccessible from the code behind (I need to expose these buttons with public properties for other views to add event handlers on them later because different views need to have different responses on the same events).
As for the dependency property and ContentPresenter, well it just did not work and I have no idea why.
here is my XAML for UserControl:
<UserControl x:Class="Syllogia.Desktop.Controls.SylToolBar"
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:local="clr-namespace:Syllogia.Desktop.Controls"
xmlns:system="clr-namespace:System;assembly=System.Runtime"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="150">
<Grid>
<telerik:RadToolBar Grid.Column="0" Grid.Row="0" x:Name="MainToolBar" AutoHideOverflowButton="True">
<telerik:RadButton x:Name="AddButton">
<Image Source="icons/Pixel/plus_math_30px.png"/>
</telerik:RadButton>
<telerik:RadButton x:Name="EditButton">
<Image x:Name="ToggleButtonImage" Source="icons/Pixel/edit_32px.png"/>
</telerik:RadButton>
<telerik:RadButton x:Name="DeleteButton">
<Image Source="icons/Pixel/erase.png"/>
</telerik:RadButton>
<telerik:RadButton x:Name="PrintButton">
<Image Source="icons/Pixel/print_30px.png"/>
</telerik:RadButton>
<telerik:RadButton x:Name="RefreshButton">
<Image Source="icons/Pixel/refresh_32px.png"/>
</telerik:RadButton>
<Grid x:Name="GridAdditionalContent">
</Grid>
</telerik:RadToolBar>
</Grid>
question 1: Is there another way to add additional content to this control from the other controls?
question 2: Is there a way to expose buttons which are declared inside a template?
I am fairly new to WPF and there may be some detail which I was not able to search and find.
In any case, Thank you for your help and sorry if I am asking stupid questions here.

Related

Setting frames datacontext

My WPF window should be able to load in different controls in same spot on the window; which should be frames to fulfill that task.
Hence i'm trying to make a frame load different pages by editing a databound string containing the Frames source. And I have managed to do that, however at the moment I have no idea how to share the frames data to the windows viewmodel hosting the frame.
I'm using MVVM and I thougth that if I could also databind a "viewmodel" to the frames datacontext, I could then both choose which page to load and which datacontext the page should use, all from the host window, therefore having access to it.
Below is my xaml.
<Window x:Class="View.Window"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window" Height="300" Width="300">
<Grid>
<Frame NavigationUIVisibility="Hidden" DataContext="{Binding WindowClass.DataContext}" Source="{Binding WindowClass.FrameURI}"/>
</Grid>
However, if I now assign the pages datacontext through this binding, instead of in the code behind, nothing gets loaded. Now I basically end up with a blank frame.
Why?
You can use Window.Resources to bind to your DataContext, then Bind to the FrameURI (You'll need to fix the appropriate namespace instead of my custom xmlns:WindowClass):
<Window x:Class="View.Window"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WindowClass="clr-namespace:WindowClass"
Title="Window" Height="300" Width="300">
<Window.Resources>
<WindowClass:MyViewModelName/>
</Window.Resources>
<Grid>
<Frame NavigationUIVisibility="Hidden" DataContext={Binding} Source="{Binding FrameURI}"/>
</Grid>
You can find a very basic tutorial here

What is the equivalent way to use Bitmap,Graphics,PictureBox & BitmapCopy() in WPF?

I'll try to explain my problem clearly.
I have a working code in WinForms that has a Board (PictureBox) that shows an image thats generated from a list of users controls (win-forms) by the function UserControl.BitmapCopy() for each user control.
This process begins with a blank image (Graphic type), and for each user control I draw it in a specific location with the function BitmapCopy() of the user control.
The result is an image that looks like a real form (with buttons,labels,etc.), but it’s just an image.
Then I show this image in a picture Box.
Now I need to implement this code in WPF, but I can’t generate an image of each user control with BitmapCopy().
I found this code that does it, so now I can generate a bitmap for each user control, but I don’t know what is the best way to create the Big Board that eventually shows a bitmap that has all the user controls images inside it, in different locations.
I would appreciate any help.
This is the equivalent in WPF:
<Window x:Class="MiscSamples.VisualBrush"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="VisualBrush" Height="300" Width="300" x:Name="Window">
<StackPanel>
<TextBlock Text="Hi, Im a Window!"/>
<TextBox Text="This is a TextBox"/>
<Slider Width="200"/>
</StackPanel>
<Window.ToolTip>
<ToolTip DataContext="{Binding PlacementTarget, RelativeSource={RelativeSource Self}}">
<Grid Height="400" Width="400">
<Grid.Background>
<VisualBrush Visual="{Binding}"/>
</Grid.Background>
</Grid>
</ToolTip>
</Window.ToolTip>
</Window>
The Window's ToolTip consists of a grid painted with VisualBrush whose Visual is the Window itself. It looks like this:
As you can see, Exactly 0 lines of C# code are required to achieve the same in WPF.

How to change maximize button color/texture

Is there any way to change the Minimize button, Maximize button, WPF window frame/border ect. using styles in the xaml?
These buttons are part of the Window Chrome, and therefore are supposed to be left for the user to decide on how they look (Windows has options for changing the color of the chrome). So if you want to take control of the Chrome, it is not as simple as a window style.
You can use the WindowStyle property to get rid of them, or make the window a Dialog-type window, but for more control, you'll need to get into creating custom chrome for your window.
If you want to go down this path, it is definitely possible, but you'll need to look at information about creating a custom chrome for your window. Here are a couple resources, but do your research and see which of these, or what other resources best meet your needs:
Code Project Library
Stack Overflow Answer w/ Links
MSDN Blog
You can remove the default Windows chrome with WindowStyle="None" and ResizeMode="NoResize" and then create whatever borders/buttons you like. E.g.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowStyle="None"
ResizeMode="NoResize"
BorderBrush="Blue"
BorderThickness="5">
<StackPanel Orientation="Horizontal"
VerticalAlignment="Top"
HorizontalAlignment="Right"
Height="20" >
<Button Content="Minimize" />
<Button Content="Restore" />
<Button Content="Close" />
</StackPanel>
</Window>

Why do my TextBoxes in different tabs of a TabControl lose their undo history?

I have a TabControl with TextBox controls in the ContentTemplate. When I type some text in one tab and switch to another tab, the Undo history in the original tab is gone when I go back.
Another problem that comes up is any text that was selected is deselected and the caret moves to the beginning of the TextBox.
If I make a window with just hardcoded TabItem controls, the undo history is preserved. The issue has something to do with my binding or templates.
Here is my XAML for the main window
<Window x:Class="TabbedTextAreaTest.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>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Command="{Binding AddNewTab}">Add Tab</Button>
<TabControl ItemsSource="{Binding Tabs}" Grid.Row="1">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Header}"/>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<TextBox Text="{Binding Content, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</Grid>
</Window>
Is there a way to preserve the undo/redo history and selected text when switching tabs without manually catching those commands?
When you use a TabControl which gets its tabs via databinding on ItemsSource, WPF doesn't keep the visual tree for each item around as you switch. Thus, when you switch from tab 1 to tab 2, then back to tab 1, the controls on tab 1 are not actually the same control instances which you saw on tab 1 the first time.
There are a number of ways around to deal with this - TabControls which have explicit TabItem instances do keep their visual trees when you switch tabs, so probably the easiest way to do it is to wrap your collection of tab items in something which makes TabItems for them.
Unfortunately right now I can't find a link to an example of how to do this. There are references to articles elsewhere on SO, but they all seem to point to pages which no longer exist, and I don't have time to dig any deeper.
The reason is simple. If you think the both operation you complain about are strictly UI operations: Undo: user editing on the UI control, selection: selection of the text on UI control.
When you swicth Tab to another and go back, what happens in WPF is that all controls are rebinded to there data (ModelView normally, or just Model) again, as if you was showing them for the first time. So they loose their UI appearance attributes.
To manage that correctly in Tab environment in WPF you need to manage Undo/Redo stack by your own.
Good luck.

Blend4, How to make WPF App(button show up pic)

How to make a button let a picture show up ?
what i Need to do, is creating 300 buttons each of these buttons will represent a unique path and pic every pic is defferent than the other? Unfortunately, WPF SketchFlow or Silverlight SketchFlow (I don't know the difference) can not be running as a program on computer. so what left is WFP app. Furthermore, i find it so difficult to just create one button linked to a pic's path!!!!.
I watched all of the Microsoft training Videos(the 5 days ones, if u dont know what i mean)http://www.microsoft.com/expression/resources/blendtraining/ . And still cant do it. I was searching for almost 4 weeks, and i still do.
Any idea how to create this essay app which require lots of work.
summery: 1-I don't know which app to use Silverlight or WPF app?(I don't know the difference)
2-i need to create a button that when i press on it, (New sorry) there will be a pic showing up in certain place that ill choose).
so in the end i need the code that will let the button work. direction for further info that ill need(websites that include vids or training by any type)
My regards SHeeDeED :)
Maybe you should start with a simple program: 1 button, showing 1 picture.
Handcraft it in XAML (no blend) and when you're stuck post a specific question here with the code.
I use Blend for most of my XAML/WPF UI design, and it works pretty well for me. I did, however, learn WPF and XAML by writing it longhand in the Visual Studio designer first. For any coding other than XAML (VB.NET, C#, C++, etc) I would highly suggest using Visual Studio as there are no bells and whistles in the Blend code window. It is essentially a colorful text editor.
As for buttons displaying images I have a couple of questions. I imagine your buttons are going to be loaded from a collection of some objects or something. By far, this is better than specifying each button in the XAML code.
I will assume your collection of objects has an ImagePath (or similarly named) property. The following should work out alright.
Load your ListBox with the Items, (see either http://www.WindowsClient.net for the old [Windows Forms] way, or read up on MVVM for the newer better way). Below is my listbox; ItemsSource is bound to the ImageCollection property on my ViewModel in this case. The items in my Imagecollection have an ImagePath property that is just a string file path to the image.
<ListBox ItemTemplate="{DynamicResource MyImageButton}" ItemsSource="{Binding ImageCollection}"/>
In Blend, you can create a DataTemplate by right clicking on the listBox, and going to Edit Additional Templates > Edit Generated Items (ItemTemplate).
From there you are just editing the layout of the items that will be created in the listbox. Below is my example of an item button with an image bound to the ImagePath property.
<DataTemplate x:Key="MyImageButton">
<Button Width="75">
<Button.Content>
<StackPanel>
<Image Source="{Binding ImagePath}" HorizontalAlignment="Left" Height="64" Width="64"/>
</StackPanel>
</Button.Content>
</Button>
</DataTemplate>
Let me know if you need more info and I can post some more resource links.
EDIT
Alright, so here is a simple little application that I made to illustrate how this can be done probably the easiest as possible. In this application, I have 3 classes:
ImageButton - It just consists of two string properties, ImagePath and ImageName.
ImageButtonCollection - Inherited from ObservableCollection, creates and adds 300 buttons (iterates 1 to 300 and sets ImagePath to "C:\Images\image{i}.png" and ImageName to "image{i}".
The MainWindow class - I will post the contents below.
MainWindow.xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ImageButtons"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="MainWindow"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<CollectionViewSource x:Key="ImageButtonsCVS"/>
</Window.Resources>
<Grid>
<ListBox Height="311" HorizontalAlignment="Left" x:Name="ListBox1" VerticalAlignment="Top" Width="268" HorizontalContentAlignment="Stretch">
<ListBox.Resources>
<DataTemplate DataType="{x:Type local:ImageButton}">
<Border Background="#5A000000" CornerRadius="5">
<Grid Height="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Grid.ColumnSpan="1" Height="30" Width="30" BorderBrush="#38FFFFFF" BorderThickness="1" Margin="5" Padding="0">
<Image Source="{Binding ImagePath}"/>
</Button>
<TextBlock Margin="0" TextWrapping="Wrap" Text="{Binding ImageName}" d:LayoutOverrides="Width, Height" Grid.Column="1" VerticalAlignment="Center" Foreground="White"/>
</Grid>
</Border>
</DataTemplate>
</ListBox.Resources>
<ListBox.ItemsSource>
<Binding Source="{StaticResource ImageButtonsCVS}"/>
</ListBox.ItemsSource>
</ListBox>
<Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="322,54,0,0" x:Name="Button1" VerticalAlignment="Top" Width="75" Click="CreateButtons" />
</Grid>
MainWindow.xaml.vb - I am more familiar with VB, but this can be easily ported to C# or whatever.
Class MainWindow
Private Sub CreateButtons(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Dim ImageButtonCVS As CollectionViewSource = Me.FindResource("ImageButtonsCVS")
ImageButtonCVS.Source = New ImageButtonCollection
End Sub
End Class
So, the ListBoxes ItemsSource property is bound to the CollectionViewSource created in the Window.Resources. The ListBox also has in it's resources a DataTemplate for the ImageButton class. Anytime an ImageButton is displayed in that listbox, that template will be used. The buttons click event is set to the CreateButtons method in the codebehind.
That method finds the CollectionViewSource resource, and sets it's source to a new instance of the ImageButtonCollection class. Once that is done, the UI is notified of an update (since the ObservableCollection has built in UI notification) and changes accordingly displaying 300 buttons with a little textblock next to them with the image name.
If you run this, create a folder on your C drive with some images named "imageX.png" with x being a number 1 to 300. Below are the other two classes so you can create/compile/run it.
ImageButton class
Public Class ImageButton
Public Property ImagePath As String
Public Property ImageName As String
Public Sub New()
End Sub
Public Sub New(ByVal Path As String, ByVal Name As String)
Me.ImagePath = Path
Me.ImageName = Name
End Sub
End Class
ImageButtonCollection class
Imports System.Collections.ObjectModel
Public Class ImageButtonCollection
Inherits ObservableCollection(Of ImageButton)
Public Sub New()
For i As Integer = 1 To 300
Me.Add(New ImageButton(String.Format("C:\Images\image{0}.png", i), String.Format("Image{0}", i)))
Next
End Sub
End Class
You never specified how you wanted the image displayed. You may not want them to be in a listbox. The beauty of WPF is that once you get it working in a listBox or whatever ItemsControl, you can easily change to another ItemsControl, or even customize one. Go into the ListBox template and change the ItemsHost to use a uniform grid or to stack items horizontally instead of vertically.

Categories

Resources