I created a sample custom control. It generates a dll after i build the project. Following is the code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace textbtn
{
public class CustomControl1 : Control
{
static CustomControl1()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1)));
}
}
}
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:textbtn">
<Style TargetType="{x:Type local:CustomControl1}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomControl1}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<TextBlock Text="This is a Test" Foreground="Aqua" Background="AntiqueWhite"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
I am including this dll in another WPF application and wants to show this custom control when user clicks a button in the application. How do i do that ?
Following is the code in my WPF application.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace TestCustomControls
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
textbtn.CustomControl1 cc = new textbtn.CustomControl1();
}
}
}
That strongly depends on what you mean by show. To just add it to the display:
AddChild(cc);
This adds it to the windows children group. This will probably blow up, since a window can only have one child. If you have a root grid called "ContentGrid", then it would be:
ContentGrid.Children.Add(cc);
The problem with both these approaches is that you don't control the position. You can set margin properties etc. to fix that of course. If your custom control were to inherit from Window (instead of control), you could do a show dialog if you want a dialog box:
cc.ShowDialog();
Of course, better than all these approaches would be to just show it in XAML instead of modifying the UI in code-behind :)
Related
This question already has answers here:
Why does WPF support binding to properties of an object, but not fields?
(2 answers)
Notify binding for static properties in static classes
(1 answer)
Closed 8 months ago.
I'm very new to C# and XAML. I'm trying to do a WPF project where there will be a good amount of data binding. Right now, I am able to do one way data binding without any problems, the issue I am facing is when I try to do two-way data binding.
This is the beginning of my Xaml file where I try to bind a text box to a static property in a static class:
<Window x:Class="interactive_fountain.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:interactive_fountain"
xmlns:include="clr-namespace:interactive_fountain.Include"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<TextBox x:Name="ip_textBox" HorizontalAlignment="Left" Height="27" Margin="250,242,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="110" Text="{Binding Source={x:Static include:Communication.ipAddressServer}, Path=include:Communication.ipAddressServer, UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="221,131,0,0" VerticalAlignment="Top" Height="47" Width="139" Click="Button_Click_1"/>
...
This is the beginning of the C# MainWindow Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;
using interactive_fountain.Include;
namespace interactive_fountain
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
Trace.WriteLine("ip: " + Communication.ipAddressServer);
}
...
And this is the beginning of the class I want to do data binding with:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;
namespace interactive_fountain.Include
{
public static class Communication
{
public static string ipAddressServer = "hello";
...
Whenever I try to do two-way data binding, the place holder "hello" doesn't appear anymore. When I write in the textBox and press the button, the output will always be ip: hello no matter what I write in the box. I have looked at a lot of threads regarding this issue but I did not find a solution that worked for me.
Does anyone know how I could make it work?
Thanks in advance!!
WPF data binding works on public properties only, your ipAddressServer is a static field (aka class variable) and not a property, so it won't be used. It's also failing at following proper naming conventions.
Your mess of a binding is the old style static binding, use {Binding Path=(w:Communication.IpAddressServer)} instead (after you fix #1, of course). w is the relevant XAML namespace definition.
Static properties don't have standard notifications for change, since static classes can't implement interfaces (for what I hope are obvious reasons). Instead WPF uses a convention-based approach of using a public static event PropertyChangedEventHandler StaticPropertyChanged and call that to notify changes. It's not clear if you want your property to be mutable, but you mentioned the change notification mechanism explicitly, so just throwing it out there.
I want to play video directly from the server in MediaElement. (The source will be the server)
I have a URL of the server:
http://videotherapy.co/dev/vt/api/dispatcher.php
And post the following json:
{"videoId":"22-1","api":"get-training-video"}
(where 22-1 is the videoId)
XAML code:
<Window x:Class="MediaElementApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="467.91" Width="1300">
<Grid>
<MediaElement x:Name="mediaElement" HorizontalAlignment="Left" Height="418" Margin="246,10,0,0" VerticalAlignment="Top" Width="1036" LoadedBehavior="Manual" UnloadedBehavior="Stop" Source="Images\Wildlife.wmv" />
<Button x:Name="play" HorizontalAlignment="Left" Margin="538,161,0,0" VerticalAlignment="Top" Width="100" Height="84" Click="play_Click" >
<Button.Background>
<ImageBrush ImageSource="Images/smiley.jpg"/>
</Button.Background>
</Button>
</Grid>
c# code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace MediaElementApp
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void play_Click(object sender, RoutedEventArgs e)
{
mediaElement.Play();
}
}
}
How to do this?
I would like for help.
The MediaElement accepts a URI as Source. Like this, it can stream the video from the web to the client application.
If this is somehow not possible in your case. You'll have to download the video to a File. Then pass the location of this file to the Source property of the MediaElement
I am trying to use WPFToolkit in my user control dll. I inserted the WPFToolkit in its reference, and my user control dll builds with no error.
Then I insert my user control dll into my application, but when my application new an object of my user control dll
MultiROIStats mroi = new MultiROIStats();
the exception occured, saying:
Additional information: Could not load file or assembly 'WPFToolkit, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
Here is my user control dll code, the constructor where the error occurs.
View xaml code:
<Window x:Class="MultiROIStats.MultiROIStats"
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:dg="http://schemas.microsoft.com/wpf/2008/toolkit"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<dg:DataGrid ItemsSource="{Binding Path=FileData}" Margin="0,30,0,0" />
<Button Height="22" HorizontalAlignment="Left" Margin="8,4,0,0"
Name="button1" VerticalAlignment="Top" Width="48"
Command="{Binding Path=GetDataCommand}">Button
</Button>
</Grid>
</Window>
View C# code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace MultiROIStats
{
using System.Windows;
using ViewModel;
//xmlns:dg="clr-namespace:Microsoft.Windows.Controls;assembly=WpfToolkit"
/// <summary>
/// Interaction logic for UserControl1.xaml
/// </summary>
public partial class MultiROIStats : Window
{
public MultiROIStats()
{
InitializeComponent(); // exception occurs here!
DataContext = new MultiROIStatsViewModel();
}
}
}
I also checked the binary folder of my user control dll, the WPFToolkei.dll is there. So I am confused, and I am wondering how can I correct this error? Thanks.
Have you maybe tried the NuGet package for the toolkit to see if that works instead?
I downloaded the sample code from
http://www.cnblogs.com/Files/sheva/RibbonStyle2.zip
I added three key files into a new project without changing the files. They are NativeMethods.cs, OfficeWindow.cs, and Generic.xaml.
I then use my new WFP form (MainWindow.xaml) to inherit from OfficeWindow.
<cc:OfficeWindow
x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cc="clr-namespace:RibbonStyle"
ResizeMode="CanResizeWithGrip"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/WpfApplication1;component/Generic.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
</Grid>
</cc:OfficeWindow>
and code behind MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using RibbonStyle;
namespace WpfApplication1
{
public partial class MainWindow : OfficeWindow
{
public MainWindow()
{
InitializeComponent();
}
}
}
The design view looks good. It shows ribbon style title bar as expected. However when I run it in the debugger it shows a classic title bar without and exceptions.
Note that if you download the original sample code from
http://www.cnblogs.com/Files/sheva/RibbonStyle2.zip
and run it directly it works.
Can anyone try my way and tell me what I have missed?
Thanks,
i have checked this example ..i think it is working fine here is the screeschot..
if thr is problem in its styling comment below..
I'm going round in circles here. I've kind of got the hang of XmlDataProvider bindings but the file I'm using seems too large to bind dynamically (50Mb doesn't work; 2Mb works). So instead I have the data loaded into classes using code generated from the XSD.
However, I can't get binding to CLR objects to work, due to my lack of knowledge. I'm using Visual Studio 2008 Pro, C# and .Net 3.5.
Here's the XAML file:
<Window x:Class="WpfObjectText.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfObjectText"
Title="Window1" Height="300" Width="300">
<Grid>
<Grid.Resources>
<ObjectDataProvider x:Key="simpleBinding" ObjectType="{x:Type local:ExampleClass}"/>
</Grid.Resources>
<StackPanel>
<TextBox Name="textBox1" Text="{Binding Path=simpleBinding}" />
</StackPanel>
</Grid>
</Window>
And the code behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfObjectText
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public ExampleClass TestInstance = new ExampleClass("Hello, world!");
public Window1()
{
InitializeComponent();
}
}
public class ExampleClass
{
public string TestString { get; set; }
public ExampleClass(string initialText)
{
TestString = initialText;
}
}
}
I've deliberately kept it simple so I can take baby steps. All I want to do here is populate the textbox from an instance of ExampleClass, and have the TestString field updated if the textbox changes (ie bidirectional). I know I can set MethodName in the binding which works to a certain extent in ListBoxes but that doesn't seem to imply bidirectional to me. Coming from a Delphi7 Win32 programmer, this is alien territory for me!
Assistance appreciated.
These are the necessary changes:
<TextBox Name="textBox1" Text="{Binding Path=TestString}" />
and then in the constructor:
DataContext = TestInstance;
If my understanding of the question is correct, you don't need Grid.Resources section at all.