I can't seem to see my custom control in the designer in blend or VS. I can't figure out what could be wrong. It works as expected when I run the app (e.g. I see a button)
Themes\Generic.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp1">
<Style TargetType="{x:Type local:MyControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyControl}">
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" >
<Button Content="Button" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
MyControl.cs
namespace WpfApp1
{
public class MyControl : Control
{
static MyControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl),
new FrameworkPropertyMetadata(typeof(MyControl)));
}
}
MainWindow.xaml
<Window
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:wpfApp1="clr-namespace:WpfApp1"
x:Class="WpfApp1.MainWindow"
mc:Ignorable="d"
Title="MainWindow">
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" >
<wpfApp1:MyControl Height="100" Width="100"/>
</StackPanel>
And in assemblyInfo.cs
[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly )]
[EDIT]
Can't explain it.
Copied all of the code into a new sln and it works as expected.
Recopied all of the code back into the original sln, removed .vs folder, rebuilt, restarted, restarted the machine, inspected the project, solution files etc... nothing it just refuses to show in one but not the other.
Related
I am attempting to customize the window style in a WPF application in VS2019 (.NET Core 3.1). I'm following along with a video, currently adding the style directly to the MainWindow.xaml. None of my style shows up in the XAML design view (in the video it does), however, the style shows correctly at runtime.
All other styles show up fine. I dug around looking for perhaps a window style I had set somewhere else but I'm not finding anything. At first, I was having an error on the inner <WindowChrome.../> saying "object of type 'Microsoft.VisualStudio.XSurface.Wpf.Window' cannot be converted to type 'System.Windows.Window'" but that issue appears to have resolved itself. I'm not sure if that is related or a clue.
Any idea what is going on and how to fix it? Or perhaps a hack to force a design-time style to take so I can see what I'm doing?
Code:
<Window x:Class="FirmwareUpdater.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:FirmwareUpdater"
xmlns:vm="clr-namespace:FirmwareUpdater.ViewModels"
mc:Ignorable="d"
WindowStyle="None"
WindowStartupLocation="CenterScreen"
x:Name="AppWindow"
Title="Firmware Updater"
Height="600" Width="800">
<Window.Resources>
<Style TargetType="{x:Type local:MainWindow}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Border Background="Gray" Padding="{Binding OuterMarginSize, FallbackValue=10}">
<Grid Background="Red">
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<WindowChrome.WindowChrome>
<WindowChrome
CaptionHeight="{Binding TitleHeight}"
ResizeBorderThickness="0"
GlassFrameThickness="0"
CornerRadius="0"/>
</WindowChrome.WindowChrome>
<Grid>
<!-- Displays pages for navigation-->
<Frame x:Name="mainFrame"
MaxHeight="600" MaxWidth="800" Margin="0,0,0,0"
NavigationUIVisibility="Hidden" />
</Grid>
</Window>
Recently, I was following this tutorial series and got this problem too, no matter which designer I use: NetFramework or NetCore.
For me, the only way to see changes during design-time is to define the ControlTemplate with a key in Window.Resources and set Window's Template as DynamicResource:
<Window ...
Template="{DynamicResource WindowBase}">
<Window.Resources>
<ControlTemplate x:Key="WindowBase" TargetType="{x:Type Window}">
</ControlTemplate>
</Window.Resources>
</Window>
I don't know how much this solution is reliable, but at least I don't have to run my app to see changes.
EDIT
You can also move the ControlTemplate from Window.Resources to some ResourceDictionary and set it as StaticResource for your Window's template.
Question: When I reference the following Resource Dictionary file in MainWindow.xaml file (shown below), why do I get the following compile error?
CustomWindowStyle resource not found
Remark:
I'm following this article where the Creating A Resource Dictionary File section is also showing the exact procedure that I am using on how to reference Resource Dictionary in MainWindow.xaml
As shown in the image below, VS2019 does CORRECCTLY recognize CustomWindowStyle when I type Style="{StaticResource ....} line in MainWindow.xaml. But at the compile time (as shown in image 2 below), it throws the above error.
I am using .NET Core 3.1. I'm not sure if the issue is related to .NET Core
When typing the line Style="{StaticResource ....} the intellisense correctly shows the option of selecting CustomWindowStyle:
At the compile time, the error shows up:
.
WindowStyle.xaml:
<ResourceDictionary x:Class="WPF_OctDelete.WindowStyle"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF_OctDelete">
<Style x:Key="CustomWindowStyle" TargetType="{x:Type Window}">
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome CaptionHeight="30"
CornerRadius="4"
GlassFrameThickness="0"
NonClientFrameEdges="None"
ResizeBorderThickness="5"
UseAeroCaptionButtons="False" />
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="Background" Value="Gray" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Grid>
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="5,30,5,5">
<AdornerDecorator>
<ContentPresenter />
</AdornerDecorator>
</Border>
<DockPanel Height="30"
VerticalAlignment="Top"
LastChildFill="False">
<TextBlock Margin="5,0,0,0"
VerticalAlignment="Center"
DockPanel.Dock="Left"
FontSize="16"
Foreground="White"
Text="{TemplateBinding Title}" />
<Button x:Name="btnClose"
Width="15"
Margin="5"
Click="CloseClick"
Content="X"
DockPanel.Dock="Right"
WindowChrome.IsHitTestVisibleInChrome="True" />
<Button x:Name="btnRestore"
Width="15"
Margin="5"
Click="MaximizeRestoreClick"
Content="#"
DockPanel.Dock="Right"
WindowChrome.IsHitTestVisibleInChrome="True" />
<Button x:Name="btnMinimize"
Width="15"
Margin="5"
VerticalContentAlignment="Bottom"
Click="MinimizeClick"
Content="_"
DockPanel.Dock="Right"
WindowChrome.IsHitTestVisibleInChrome="True" />
</DockPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
MainWindow.xaml:
<Window x:Class="WPF_OctDelete.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:WPF_OctDelete"
mc:Ignorable="d"
Style="{StaticResource CustomWindowStyle}"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="WindowStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Button x:Name="btnTest" Content="Test"/>
</Grid>
</Window>
Your resource is being loaded after the window is loaded and so it cannot find the resource during the window loading event. So your method isn't going to work that way.
You need to put that resource in your App.xaml file, see - How to Set the Source of an Image in XAML and in Code Behind to an image in another project in WPF
In your case (in App.xaml) - '
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="WindowStyle.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
And then you can use your key in the Window -
<Window x:Class="WPF_OctDelete.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:WPF_OctDelete"
mc:Ignorable="d"
Style="{StaticResource CustomWindowStyle}"
Title="MainWindow" Height="450" Width="800">
<!--Rest of your UI Elements-->
</Window>
No need to add resources to your window, since its added to the main app file. That resource will be available across your entire project (available for other windows/controls)
(Edit: further clarification - When you add something as a "StaticResource" to your window style, but load the actual resource later, the window "loaded" event is not going to pick it up. Another solution is to refer your style as "DynamicResource", so the style during the "loaded" event is not static and will be updated when it captures the new resource.)
The XAML processor reads the XAML file from top to bottom so by the time it tries to resolve the CustomWindowStyle resource, it hasn't yet loaded the ResourceDictionary.
You could easily fix this by setting the Resources property before you set the Style property:
<Window x:Class="WPF_OctDelete.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:WPF_OctDelete"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="WindowStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Window.Style>
<StaticResource ResourceKey="CustomWindowStyle"/>
</Window.Style>
<Grid>
<Button x:Name="btnTest" Content="Test"/>
</Grid>
</Window>
The order matters.
We are building a WPF kiosk application.
We need to disable CUT COPY PASTE and RIGHT-CLICKs
Please how can this be done?
This SO post does not give a centralized solution for all forms:
How to suppress Cut, Copy and Paste Operations in TextBox in WPF?
You need to add a Style in your App.xaml in which you define:
<Style TargetType="TextBox">
<!-- OR -->
<Style TargetType="{x:Type TextBox}">
<Setter Property="ContextMenu" Value="{x:Null}"/>
</Style>
But this will only work for the Items that are NOT in a DataTemplate.
UPDATE:
App.xaml:
<Application x:Class="TestApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestApp"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="ContextMenu" Value="{x:Null}"/>
</Style>
</Application.Resources>
And here is the MainWindow.xaml:
<Window x:Class="TestApp.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"
xml:lang="en-GB"
xmlns:local="clr-namespace:TestApp"
xmlns:converter="clr-namespace:TestApp.Converters"
mc:Ignorable="d"
Height="478.889" Width="903.889">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.3*"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel>
<TextBox Name="txtBx" MinHeight="150"
VerticalAlignment="Top" AutoWordSelection="True"
MaxLines="10"
TextWrapping="WrapWithOverflow"
SelectionChanged="txtBx_TextHighlighted"
ToolTip="{x:Null}"
Margin="10"/>
</StackPanel>
</Grid>
If you Right Click on the TextBox you will not have any ContextMenu available to you.
UPDATE 2:
Continuing from our chat, the TextBox was referencing other styles which were overriding whatever we set in the App.xaml. As the external styles were loaded after the App.xaml.
I created my resource dictionary and can access styles in it, but how (If possible) would I reference an entire control from it?
Here's the resourcedictionary:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="MainWindowStyle" TargetType="Window">
<Setter Property="Background" Value="Transparent"></Setter>
<!--Can access this-->
</Style>
<Window x:Key="CustomWindow" Background="Transparent">
<!--Want to access this-->
</Window>
</ResourceDictionary>
Here's the main window xaml file:
<Window x:Class="MyNamespace.MyWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="640" Width="960" >
<!--setting Style={StaticResource MainWindowStyle} adds the style but I want this window to be replaced by the one in the resourcedictionary-->
<Grid>
</Grid>
</Window>
So I basically want to replace the window in the xaml file with the one created in the resource dictionary.
You can certainly host something like a UserControl within another control.
E.g. a ContentControl
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window x:Key="CustomUserControl" Background="Transparent">
<!--Want to access this-->
</Window>
</ResourceDictionary>
Then:
<ContentControl Content="{StaticResource ResourceKey=CustomUserControl}" />
I suspect that's not quite what you're after, but it's not clear what you may/may not have within the Window that's of interest.
I will use XAMLReader to load wpf screens.
I have some ControlTemplates on Buttons.xaml file and i am keeping it in a common class library (ClassLibrary1).
Buttons.xaml is like that:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ControlTemplate x:Key="LeftButton" TargetType="{x:Type Button}">
// Some codes
</ControlTemplate>
<ControlTemplate x:Key="RightButton" TargetType="{x:Type Button}">
// Some codes
</ControlTemplate>
</ResourceDictionary>
On main WPF project, this dll is added as reference.
My xaml is like that:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="800" Height="600">
<Grid>
<Grid.Resources>
<ResourceDictionary x:Key="testSource">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary x:Name="s" Source="pack://application:,,,/ClassLibrary1;component/Buttons.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Grid.Resources>
<Button Template="{DynamicResource RightButton}" Content="TestBtn" HorizontalAlignment="Left" Width="100" Height="100" Margin="474,529,0,0" ></Button>
</Grid>
</UserControl>
When i use Template="{DynamicResource RightButton}" template is not loaded correctly (actually there is no sign of button on screen).
Also there is no error about loading the resourcedictionary.
I couldn't find, what should i use in order to load template on this button. Can anyone help me?