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
}
}
}
Related
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
{
}
}
I make an easy demo by WPF, here is the XAML:
<Window x:Class="WpfApp1.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:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid PreviewMouseLeftButtonDown="Grid_PreviewMouseLeftButtonDown" Background="White">
<Border Height="100" Width="100" Background="Red" PreviewMouseLeftButtonDown="Border_PreviewMouseLeftButtonDown"></Border>
</Grid>
</Window>
And here is 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 WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Border_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("Border");
}
private void Grid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("Grid");
}
}
}
I wanna do that if I press the border, it only activates the "Border" message box but not with the "Grid" message box also.
How can I do it? Would you please help me?
Thank you.
you can replace PreviewMouseLeftButtonDown with MouseDown.
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);
};
}
}
}
I am trying to use the Storyboard's Completed event to indicate when an audio file has finished playing.
However, it seems .Net behaves differently when playing mp3 and wav files, and the event is triggered only for WAV.
Here is a XAML and code that demonstrate the problem:
<Window x:Class="WpfApplication1.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"
x:Name="mainWind">
<Window.Resources>
<Storyboard x:Key="mp3StoryBoard" Completed="Storyboard_Completed">
<MediaTimeline Source="001.mp3" Storyboard.TargetName="mediaEl" >
</MediaTimeline>
</Storyboard>
<Storyboard x:Key="wavStoryBoard" Completed="Storyboard_Completed">
<MediaTimeline Source="001.wav" Storyboard.TargetName="mediaEl" >
</MediaTimeline>
</Storyboard>
</Window.Resources>
<Grid>
<MediaElement x:Name="mediaEl" Height="120" HorizontalAlignment="Left" Margin="120,94,0,0" VerticalAlignment="Top" Width="160" />
<Button Content="Play MP3" Height="23" HorizontalAlignment="Left" Margin="148,260,0,0" Name="btnMP3" VerticalAlignment="Top" Width="75" Click="button1_Click" />
<Button Content="Play WAV" Height="23" HorizontalAlignment="Left" Margin="267,260,0,0" Name="btnWAV" VerticalAlignment="Top" Width="75" Click="btnWAV_Click" />
</Grid>
</Window>
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.Media.Animation;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
Storyboard sb = (Storyboard)this.mainWind.Resources["mp3StoryBoard"];
sb.Begin();
}
private void Storyboard_Completed(object sender, EventArgs e)
{
MessageBox.Show(" Storyboard finished");
}
private void btnWAV_Click(object sender, RoutedEventArgs e)
{
Storyboard sb = (Storyboard)this.mainWind.Resources["wavStoryBoard"];
sb.Begin();
}
}
}
Will be glad if anyone has an idea for the reason for that and how to overcome it.
You don't have an attached event handler.
You need a
sb.Completed +=Storyboard_Completed;
before
The WPF MediaKit includes a MediaElement replacement, which may work better with mp3 files.
I have 2 user controls one named Filters and one named FilterItem
Filter looks like this:
<UserControl xmlns:my="clr-namespace:AttorneyDashboard.Views.UserControls" x:Class="AttorneyDashboard.Views.UserControls.Filters"
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:helpers="clr-namespace:AttorneyDashboard.Helpers"
mc:Ignorable="d"
d:DesignHeight="150" d:DesignWidth="590" x:Name="FiltersRoot">
<Grid>
<ListBox x:Name="myListBox" ItemsSource="{Binding Path=FilterItems, ElementName=FiltersRoot}" >
<ListBox.ItemTemplate>
<DataTemplate>
<my:FilterItem ColumnsList="{Binding Path=Columns_, ElementName=FiltersRoot}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>
Code Behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Data;
using System.Collections.ObjectModel;
using System.Diagnostics;
using AttorneyDashboard.Helpers;
namespace AttorneyDashboard.Views.UserControls
{
public class MyItems
{
public string Header { get; set; }
}
public partial class Filters : UserControl
{
public Filters()
{
InitializeComponent();
}
private DependencyProperty FilterItemsProperty = DependencyProperty.Register("FilterItems", typeof(ObservableCollection<FilterDescriptor>), typeof(Filters), new PropertyMetadata(null, new PropertyChangedCallback(OnChangeFilterItems)));
public ObservableCollection<FilterDescriptor> FilterItems
{
get
{
return (ObservableCollection<FilterDescriptor>)GetValue(FilterItemsProperty);
}
set
{
SetValue(FilterItemsProperty, value);
}
}
public static void OnChangeFilterItems(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
}
public List<MyItems> Columns_
{
get
{
List<MyItems> list = new List<MyItems>();
list.Add(new MyItems() { Header = "test1" });
list.Add(new MyItems() { Header = "test2" });
list.Add(new MyItems() { Header = "test3" });
return list;
}
}
}
}
FilterItems looks like this
<UserControl x:Class="AttorneyDashboard.Views.UserControls.FilterItem"
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"
mc:Ignorable="d"
d:DesignHeight="23" d:DesignWidth="590" xmlns:my="clr-namespace:AttorneyDashboard.Helpers" x:Name="FilterItemRoot">
<StackPanel Orientation="Horizontal">
<ComboBox Height="23" HorizontalAlignment="Left" Name="FieldName" VerticalAlignment="Top" Width="120" Margin="5,0,0,0" ItemsSource="{Binding Path=ColumnsList, ElementName=FilterItemRoot}" SelectedItem="{Binding PropertyPath, Mode=TwoWay}" DisplayMemberPath="Header"/>
</StackPanel>
</UserControl>
Code behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using AttorneyDashboard.Helpers;
using System.Windows.Data;
namespace AttorneyDashboard.Views.UserControls
{
public partial class FilterItem : UserControl
{
public FilterItem()
{
InitializeComponent();
}
private DependencyProperty ColumnsListProperty = DependencyProperty.Register("ColumnsList", typeof(List<MyItems>), typeof(FilterItem), new PropertyMetadata(null, new PropertyChangedCallback(OnChangeColumns)));
public List<MyItems> ColumnsList
{
get
{
return (List<MyItems>)GetValue(ColumnsListProperty);
}
set
{
SetValue(ColumnsListProperty, value);
}
}
public static void OnChangeColumns(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
}
}
}
The number of FilterItems is ok (this means that FilterItems binding works ok), but only the Combobox of the last FilterItem is populated...
And I do not know what exactly is wrong...
Update:
I found why but I stll do not know a solution...
It seams that the content of FilterItem is binded before his properties are..
So the combobox in FilterItem is binded before the Columns property is binded...
Your code in FilterItem
private DependencyProperty ColumnsListProperty = DependencyProperty
.Register("ColumnsList", typeof(List<MyItems>), typeof(FilterItem),
new PropertyMetadata(null, new PropertyChangedCallback(OnChangeColumns)));
Please, make it static:
private **static** DependencyProperty ColumnsListProperty = DependencyProperty
.Register("ColumnsList", typeof(List<MyItems>), typeof(FilterItem),
new PropertyMetadata(null, new PropertyChangedCallback(OnChangeColumns)));
Thats it.
P.S. : in Filters make dependency property static too, generally do it anywhere :)
You have placed a x:Name attribute directly on your UserControl elements. Don't do that. Use this pattern instead:-
<UserControl x:Class="AttorneyDashboard.Views.UserControls.FilterItem"
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"
mc:Ignorable="d"
d:DesignHeight="23" d:DesignWidth="590" xmlns:my="clr-namespace:AttorneyDashboard.Helpers" >
<StackPanel Orientation="Horizontal" x:Name="LayoutRoot">
<ComboBox Height="23" HorizontalAlignment="Left" Name="FieldName" VerticalAlignment="Top" Width="120" Margin="5,0,0,0" ItemsSource="{Binding Path=Parent.ColumnsList, ElementName=LayoutRoot}" SelectedItem="{Binding PropertyPath, Mode=TwoWay}" DisplayMemberPath="Header"/>
</StackPanel>
</UserControl>
You are not in control of name assigned to the user control, that belongs in the scope of the Xaml the uses your UserControl. If your code internally requires that the containing UserControl have a specific name then things are likely to break.