How can I create a new usercontrol inherit from ComboBox? - wpf

I wanna to create a new usercontrol,it is inherit from ComboBox.I will add some new property to it, and rewrite its ControlTemplate.
Here is XAML:
<ComboBox x:Class="Pesticide.CustomUserControls.ComboxUserControl"
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:Pesticide.CustomUserControls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<ComboBox.Resources>
<ControlTemplate TargetType="{x:Type ComboBox}" x:Key="{x:Type ComboBox}">
<Grid></Grid>
</ControlTemplate>
</ComboBox.Resources>
</ComboBox>
And here is code behind:
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 Pesticide.CustomUserControls
{
public partial class ComboxUserControl : ComboBox
{
public ComboxUserControl()
{
InitializeComponent();
}
}
}
However,I just wrote these code,but WPF throw an error which is "InvalidCastException: Unable to cast object of type 'System.Windows.Controls.ControlTemplate' to type 'System.Windows.Style'."
What's wrong with my code?Would you please to help me?Thank you.

What's wrong with my code?
Using a type as resource key is the way WPF handles default Styles.
So a resource with
x:Key="{x:Type ComboBox}"
can't be a ControlTemplate. It has to be a Style.
However, it is simpler to directly set the Template property:
<ComboBox ...>
<ComboBox.Template>
<ControlTemplate TargetType="ComboBox">
...
</ControlTemplate>
</ComboBox.Template>
</ComboBox>

Related

MSVS - WPF - How do I make ProjectName.csproj build App.xaml and App.xaml.cs last?

My WPF project has App.xaml require other pieces of project code to be built before it gets built. Despite App.xaml's dependency on those classes and xaml files, Visual Studio wants to build it first before anything else can get built.
For further information, here's the dependencies that are not getting addressed when I build from scratch.
XAML namespaces:
xmlns:views="clr-namespace:ProjectName.Views"
xmlns:viewmodels="clr-namespace:ProjectName.ViewModels"
XAML namespace implementations:
<DataTemplate DataType="{x:Type viewmodels:HomeViewModel}">
<views:HomeView/>
</DataTemplate>
HomeViewModel is a class in ...ViewModels.
HomeView is a class and XAML file in ...Views.
I know that the .csproj build order is the main problem, because I built the solution omitting the datatemplates and got no errors, and when I built after putting them back in I am still fine.
But when I cleaned the solution and rebuilt, I get errors up the wazoo!
I am making an MVVM application and I absolutely need App.xaml to be built last, as otherwise it would be difficult to make further iterations (as in, more Views / ViewModels) to this project.
How do I alter the .csproj files so that this happens?
I'm using MS Visual Studio Community 2019.
Also, I tried looking through build targets and overriding them but I can't figure out how to make it so that certain pieces of source code get built last.
Additional context:
App.xaml
<Application x:Class="ProjectName.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ProjectName;assembly=ProjectName"
xmlns:views="clr-namespace:ProjectName.Views"
xmlns:viewmodels="clr-namespace:ProjectName.ViewModels"
StartupUri="MainWindow.xaml">
<Application.Resources>
<!--
<DataTemplate DataType="{x:Type viewmodels:MainViewModel}">
<views:MainView/>
</DataTemplate>
-->
<DataTemplate DataType="{x:Type viewmodels:NGViewModel}">
<views:NGView/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:HomeViewModel}">
<views:HomeView/>
</DataTemplate>
<!---->
</Application.Resources>
</Application>
HomeView.xaml.cs
using System;
using System.Collections.Generic;
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 ProjectName.Views
{
/// <summary>
/// Interaction logic for HomeView.xaml
/// </summary>
public partial class HomeView : UserControl
{
public HomeView()
{
InitializeComponent();
}
}
}
HomeView.xaml
<UserControl x:Class="ProjectName.Views.HomeView"
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:ProjectName.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="Black">
</Grid>
</UserControl>
HomeViewModel.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace ProjectName.ViewModels
{
public class HomeViewModel : BaseViewModel
{
}
}
BaseViewModel.cs (bonus - parent class of HomeViewModel)
using System;
using System.Collections.Generic;
using System.Text;
namespace Prototype7022.ViewModels
{
public class BaseViewModel
{
}
}

if itemcontainerstyle is inside DataTemplate and a call the the main window is used an System.NullReferenceExc on start-up but works fine if ignored

when i try to call a event from the main wind if a control is in a template in itemcontainerstyle
when the run a System.NullReferenceException: 'Object reference not set to an instance of an object.' is displayed over InitializeComponent(); which if i continue it works fine as indented which is weird because an error message is normally there to tell you if something didn't work
below is the a cut down vision of my program only the things that case the error message to come up (i have tried it in different templates)
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 wpf_test_zone
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void test(object sender, RoutedEventArgs e)
{
}
}
Title="MainWindow" Height="450" Width="800">
<Grid>
<TabControl x:Name="tabcontrol_1">
<TabControl.ContentTemplate>
<DataTemplate>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
<ListView>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<TabControl x:Name="tabcontrol_2">
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding}"/>
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel>
<Grid>
<Button x:Name="but" Click="test">
</Button>
</Grid>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
edit -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
the error message that comes up

Avoid dropdown selection change event during view load

Grid contains dropdown control. I want to avoid selection change event during view load. What is the best way to achieve that?
Well i don't know what dropdown control is in WPF
I have tried with combobox and SelectionChanged event in not firing at form load
Here's my code
<Window x:Class="Q6.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:Q6"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ComboBox SelectionChanged="ComboBox_SelectionChanged"
Height="30" Width="100">
<ComboBoxItem>Alpha</ComboBoxItem>
<ComboBoxItem>Beta</ComboBoxItem>
<ComboBoxItem>Gamma</ComboBoxItem>
</ComboBox>
</Grid>
</Window>
And the code-behind :
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 Q6
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
//Not firing at load time
}
}
}

repeat button wpf not firing off click event

Hello community I have the following xaml.
<UserControl x:Class="Sample.SampleController"
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"
mc:Ignorable="d"
d:DesignHeight="410" d:DesignWidth="324">
<UserControl.Resources>
<Style x:Key="buttonON" TargetType="RepeatButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RepeatButton">
<Grid Width="80"
Height="80">
<Image Source="/Sample;component/icons/altitude_up_yellow.png"
Stretch="Fill" RenderOptions.BitmapScalingMode="Fant"/>
<ContentPresenter HorizontalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid Name="DriveGrid" Background="#C9000000" Width="324" Height="410">
<RepeatButton HorizontalAlignment="Left" x:Name="button1" VerticalAlignment="Top" IsEnabled="True" Style="{StaticResource buttonON}" Margin="232,297,0,0" Delay="100" Interval="200" Width="80" Height="80"/>
</Grid>
</UserControl>
And the following Code Behind
using System;
using System.Collections.Generic;
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;
using System.Diagnostics;
using System.Windows.Controls.Primitives;
namespace Sample {
/// <summary>
/// Interaction logic for UserControl1.xaml
/// </summary>
public partial class SampleController : UserControl {
public SampleController() {
InitializeComponent();
button1.Click += new RoutedEventHandler(UpBtn_Click);
}
void UpBtn_Click(object sender, RoutedEventArgs e) {
Console.WriteLine("Click");
}
}
}
My question, why doesn't the repeat button fire off continously when I press and hold?
Thank you for your help.
To sum up comments. Even though I am not able to reproduce the problem stated in the question, as the code above works fine for me, I have found very similar issue in RepeatButton fires event only once! article. There is no definite answer what's causing the issue but it may give some clues to what to try

Custom ItemControl for ListBox

I want to add new DependencyProperty to ListBoxItem class which used in ListBox control. I need to add IsEditing property. When user will does long click on my ListBoxItem I will change it IsEditing property to True and then in Trigger of this property will be style changing. Actually the idea to change TextBlock to TextBox in style.
I hope my explanation is clear. Does it make any sense, or there is exist more simple way?
Thanks
See the XAML below - A child of DataTemplate is your item's template. You can use built-in WPF elements like Grid, Canvas etc. or your own user/custom control. You can create EditableItem control and use it to handle long mouse clicks etc.
This is not the most elegant way of doing this, but probably the simplest one. The more advanced approach would involve the usage of attached behaviors, which elliminates need for custom/user controls. Also, look at VisualStateManager class, it'll simplify switching between different 'modes' of your editable item (that's what I'd use for it anyway).
<Window x:Class="WpfApplication2.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>
<ListBox x:Name="l">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Height="30" Background="Green" Width="100">
<TextBlock Text="{Binding}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
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 WpfApplication2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Loaded += (o, e) =>
{
this.l.ItemsSource = Enumerable.Range(1, 3);
};
}
}
}

Resources