WPF UI Window not updating - c#

I have a window which contains a label and an animated spinner. This window is a kind of splash screen saying "Loading...".
It is a simple basic window:
<Window x:Class="MyWin.SplashScreen"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
<!-- Grid and within the label at row 0, and the spinner at row 1 -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="50*"></RowDefinition>
<RowDefinition Height="20*"></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">Loading...</Label>
<Grid Name="mySpinner" Grid.Row="1"></Grid>
</Grid>
</Window>
Code behind:
public partial class SplashScreen: Window
{
public SplashScreen()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
System.Windows.Forms.Integration.WindowsFormsHost host = new System.Windows.Forms.Integration.WindowsFormsHost();
// Here I instantiate the spinner control and show in UI
UCSpinner myUCSpinner = new UCSpinner();
host.Child = myUCSpinner;
this.mySpinner.Children.Add(host);
}
}
The animated spinner is a control that is instantiated and loaded in the window load event: Window_Loaded
Then from my main wpf window, I have a button. When button is clicked I create a background worker, I start the background worker and after that I call the splash window above indicated. See below.
Main window button:
<Button Grid.Column="1" Width="75" Command="{Binding LaunchOperationCommand}" Content="Calculate" HorizontalAlignment="Right">
</Button>
Code behind:
RelayCommand launchOperationCommand;
public ICommand LaunchOperationCommand
{
get
{
if (launchOperationCommand== null)
launchOperationCommand= new RelayCommand(param => this.DoLongOperation(), param => true);
return launchOperationCommand;
}
}
private void DoLongOperation()
{
BWorker = null;
if (BWorker == null)
{
BWorker = new BackgroundWorker();
BWorker.WorkerReportsProgress = false;
BWorker.WorkerSupportsCancellation = false;
BWorker.DoWork += new DoWorkEventHandler(BWorker_LongOp_DoWork);
BWorker.ProgressChanged += new ProgressChangedEventHandler(BWorker_LongOp_ProgressChanged);
BWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BWorker_LongOp_RunWorkerCompleted);
}
if (BWorker.IsBusy != true)
{
BWorker.RunWorkerAsync();
ShowSplashScreen();
}
}
private System.Windows.Window splashWindow = null;
private void ShowSplashScreen()
{
if (splashWindow == null)
{
splashWindow = new SplashScreen();
}
if (splashWindow .IsVisible == false)
splashWindow .ShowDialog();
}
The problem is the following: The label in the splash screen is displayed but the spinner not.

Related

C# UWP Listview/GridView mark of selected item

I am creating UWP app, and I maked external arrow "marker" of selected item in listview...
Like this:
I have managed to achieve this with next code:
var current = lvMain.Items.FirstOrDefault(a => (a as MyModel).Selected) as MyModel;
ListViewItem selected = lvMain.ContainerFromItem(current) as ListViewItem;
GeneralTransform generalTransform1 = gvEpg.TransformToVisual(selected);
Point currentPoint = generalTransform1.TransformPoint(new Point());
In Scroll change event I am calling this and set the arrow position by the Point of my item. And this is working.
But, I want to simplified this. Is there any kind of binding or something like that, that would make arrow always follow the item?
Here's the sample.
XAML MainPage:
<Page.Resources>
<DataTemplate x:Key="DataTemplate">
<Canvas Height="80" Width="200">
<TextBlock Text="{Binding}"/>
</Canvas>
</DataTemplate>
</Page.Resources>
<StackPanel Orientation="Horizontal">
<ListView x:Name="ListView" Width="400"
SelectionChanged="ListView_OnSelectionChanged"
ItemTemplate="{StaticResource DataTemplate}"/>
<Canvas x:Name="ParentCanvas">
<Image x:Name="Arrow"
Stretch="UniformToFill" Width="200" Height="80"
Source="Assets/Red_Left_Arrow.png"/>
</Canvas>
</StackPanel>
Code behind:
private readonly List<string> _names = new List<string>();
private Visual _rectangleVisual;
private Visual _parentVisual;
public MainPage()
{
InitializeComponent();
Loaded += MainPage_Loaded;
}
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 32; i++)
{
_names.Add("item " + i);
}
ListView.ItemsSource = _names;
_parentVisual = ElementCompositionPreview.GetElementVisual(ParentCanvas);
_rectangleVisual = ElementCompositionPreview.GetElementVisual(Arrow);
var border = VisualTreeHelper.GetChild(ListView, 0) as Border;
var scrollViewer = border.Child as ScrollViewer;
var scrollerProperties = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(scrollViewer);
var offsetExpressionAnimation = _rectangleVisual.Compositor.CreateExpressionAnimation("Scroller.Translation.Y");
offsetExpressionAnimation.SetReferenceParameter("Scroller", scrollerProperties);
_rectangleVisual.StartAnimation("Offset.Y", offsetExpressionAnimation);
}
private void ListView_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var listViewItem = ListView.ContainerFromItem(ListView.SelectedItem) as ListViewItem;
var listItemVisual = ElementCompositionPreview.GetElementVisual(listViewItem);
_parentVisual.Offset = new Vector3(_parentVisual.Offset.X, listItemVisual.Offset.Y, 0);
}
Looks like what you asked for:

How to position buttons randomly?

How can I position a button img randomly on a grid in XAML? I tried it, but it doesn't work!
This is my code:
public void randomButton()
{
Button newBtn = new Button();
newBtn.Content = "A New Button";
panelButton.Children.Add(newBtn);
Grid.SetRow(newBtn, 1);
Random generator = new Random();
newBtn = generator.Next(1, 100);
}
You need to set the Grid.Row dependency property on the Button.
XAML
<Window x:Class="WpfApplication1.MainWindow" [...] Loaded="Window_Loaded">
<Grid Name="grdMain">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
</Grid>
</Window>
C#
using System;
using System.Windows;
using System.Windows.Controls;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
void Window_Loaded(object sender, RoutedEventArgs e)
{
//creating the button
Button b = new Button() { Content = "Click me!" };
//when clicked, it'll move to another row
b.Click += (s, ea) => ChangeButtonRow(s as Button);
//adding the button to the grid
grdMain.Children.Add(b);
//calling the row changing method for the 1st time, so the button will appear in a random row
ChangeButtonRow(b);
}
void ChangeButtonRow(Button b)
{
//setting the Grid.Row dep. prop. to a number that's a valid row index
b.SetValue(Grid.RowProperty, new Random().Next(0, grdMain.RowDefinitions.Count));
}
}
}
I hope this helps. :)

WPF Drag and Drop with Adorner using mouse and touch

I want this to be good question, so I'll write in details what I would like to achieve, what I've found on the internet and I show what I've done so far and what I've tried.
I need to add drag and drop functionality to my application. I have Images (basically controls) that I want to drag to items of listbox.
Here is sample UI:
And here is usage I have now:
As You can see I'm able to drag one of four images and drop it over listbox item.
If I move image over correct target (listbox image) image near cursor disappears and everything works fine, but when I don't drop image on list item (I release mouse) that image stays on screen.
I've based my solution on answers to this question, and I'm unable to remove that unwanted window (image near cursor)
My XAML looks like this:
<Window x:Class="DragDrop.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Drag'n'Drop" Height="350" Width="525"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<ListBox HorizontalAlignment="Right" HorizontalContentAlignment="Stretch" Height="300" Margin="0,10,10,0" VerticalAlignment="Top" Width="234" ItemsSource="{Binding People}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" AllowDrop="True" PreviewDrop="UIElement_OnPreviewDrop">
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
<ProgressBar Height="20" Value="{Binding Points}" Margin="0,0,0,0"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Image HorizontalAlignment="Left" Height="72" Margin="10,10,0,0" VerticalAlignment="Top" Width="72" Source="Images/coins-60000-icon.png" RenderTransformOrigin="0.5,0.5"
PreviewMouseLeftButtonDown="OnMouseTouchDown"
PreviewTouchDown="OnMouseTouchDown"
PreviewGiveFeedback="UIElement_OnPreviewGiveFeedback" Tag="10"/>
<Image HorizontalAlignment="Left" Height="72" Margin="87,10,0,0" VerticalAlignment="Top" Width="72" Source="Images/coins-700000-icon.png" RenderTransformOrigin="0.5,0.5"
PreviewMouseLeftButtonDown="OnMouseTouchDown"
PreviewTouchDown="OnMouseTouchDown"
PreviewGiveFeedback="UIElement_OnPreviewGiveFeedback" Tag="20"/>
<Image HorizontalAlignment="Left" Height="72" Margin="10,87,0,0" VerticalAlignment="Top" Width="72" Source="Images/coins-7000-icon.png" RenderTransformOrigin="0.5,0.5"
PreviewMouseLeftButtonDown="OnMouseTouchDown"
PreviewTouchDown="OnMouseTouchDown"
PreviewGiveFeedback="UIElement_OnPreviewGiveFeedback" Tag="30"/>
<Image HorizontalAlignment="Left" Height="72" Margin="87,87,0,0" VerticalAlignment="Top" Width="72" Source="Images/coins-700-icon.png" RenderTransformOrigin="0.5,0.5"
PreviewMouseLeftButtonDown="OnMouseTouchDown"
PreviewTouchDown="OnMouseTouchDown"
PreviewGiveFeedback="UIElement_OnPreviewGiveFeedback" Tag="40"/>
</Grid>
</Window>
And code behind:
public partial class MainWindow
{
private readonly ObservableCollection<Person> _people = new ObservableCollection<Person>();
public ObservableCollection<Person> People
{
get { return _people; }
}
public MainWindow()
{
InitializeComponent();
_people.Add(new Person() {Name = "Person1", Points = 10});
_people.Add(new Person() {Name = "Person2", Points = 0});
_people.Add(new Person() {Name = "Person3", Points = 40});
}
private void OnMouseTouchDown(object sender, InputEventArgs e)
{
var item = sender as Image;
if (item == null) return;
var draggedItem = item;
var points = Convert.ToInt32(draggedItem.Tag);
CreateDragDropWindow(draggedItem);
System.Windows.DragDrop.DoDragDrop(draggedItem, points, DragDropEffects.Move);
}
private Window _dragdropWindow;
private void CreateDragDropWindow(Visual dragElement)
{
_dragdropWindow = new Window
{
WindowStyle = WindowStyle.None,
AllowsTransparency = true,
AllowDrop = false,
Background = null,
IsHitTestVisible = false,
SizeToContent = SizeToContent.WidthAndHeight,
Topmost = true,
ShowInTaskbar = false
};
Rectangle r = new Rectangle
{
Width = ((FrameworkElement) dragElement).ActualWidth/2,
Height = ((FrameworkElement) dragElement).ActualHeight/2,
Fill = new VisualBrush(dragElement)
};
_dragdropWindow.Content = r;
Win32Point w32Mouse = new Win32Point();
GetCursorPos(ref w32Mouse);
_dragdropWindow.Left = w32Mouse.X;
_dragdropWindow.Top = w32Mouse.Y;
_dragdropWindow.Show();
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetCursorPos(ref Win32Point pt);
[StructLayout(LayoutKind.Sequential)]
internal struct Win32Point
{
public Int32 X;
public Int32 Y;
};
private void UIElement_OnPreviewGiveFeedback(object sender, GiveFeedbackEventArgs e)
{
Win32Point w32Mouse = new Win32Point();
GetCursorPos(ref w32Mouse);
_dragdropWindow.Left = w32Mouse.X;
_dragdropWindow.Top = w32Mouse.Y;
}
private void UIElement_OnPreviewDrop(object sender, DragEventArgs e)
{
//var droppedData = e.Data.GetData(typeof(Image)) as Image;
var droppedData = (Int32) e.Data.GetData(typeof (Int32));
var stackPanel = sender as StackPanel;
if (stackPanel != null)
{
var student = stackPanel.DataContext as Person;
//int targetIndex = _people.IndexOf(student);
if (student != null) student.Points += droppedData;
}
if (_dragdropWindow != null)
{
_dragdropWindow.Close();
_dragdropWindow = null;
}
}
}
public class Person : INotifyPropertyChanged
{
private string _name;
private int _points;
public string Name
{
get { return _name; }
set
{
if (value == _name) return;
_name = value;
OnPropertyChanged();
}
}
public int Points
{
get { return _points; }
set
{
if (value == _points) return;
_points = value;
if (_points >= 100)
{
_points -= 100;
Debug.WriteLine("100!");
}
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
I found over the internet that I can use class that extends Adorner and I found some examples:
http://nonocast.cn/adorner-in-wpf-part-5-drag-and-drop/ - (WaybackMachine archive link)
http://www.zagstudio.com/blog/488#.VfiMSBHtmko
http://www.infragistics.com/community/blogs/alex_fidanov/archive/2009/07/28/drag-amp-drop-with-datapresenter-family-controls.aspx
https://github.com/punker76/gong-wpf-dragdrop
but all of them show how to drag items from collections (ItemsControls). Third link was promising, but I wasn't able to adopt it to my needs.
So my questions are:
How can I hide that small image window in my example when I cancel drag (MouseUp or incorrect drag target)
Show I use Adorner and how can I use it in my code? I need to show it when I start drag and hide when I drop Image correctly or I cancel drag or drop target is incorrect
I'm starting with WPF so please try to understand my frustration - I've spend last two evenings and night trying to get this working.
1) Modify your OnMouseTouchDown handler to include assigning ContinueDragHandler to dragged item before starting the drag, like this
private void OnMouseTouchDown(object sender, InputEventArgs e)
{
var item = sender as FrameworkElement;
if (item == null) return;
var draggedItem = item;
var points = Convert.ToInt32(draggedItem.Tag);
CreateDragDropWindow(draggedItem);
System.Windows.DragDrop.AddQueryContinueDragHandler(draggedItem, DragContrinueHandler);
System.Windows.DragDrop.DoDragDrop(draggedItem, points, DragDropEffects.Move);
}
And the handler itself:
public void DragContrinueHandler(object sender, QueryContinueDragEventArgs e)
{
if (e.Action == DragAction.Continue && e.KeyStates != DragDropKeyStates.LeftMouseButton)
{
_dragdropWindow.Close();
}
}
2) I believe that creating a new window to display image next to a cursor is a dirty dirty hack. There are plenty of various articles around about using adorners with drag'n'drop. Althought your approach works and doesn't require a lot of code. Adorners do, on the other hand. I think you should create another question, if you fail following certain tutorial, with code examples and what steps you took

windows phone bing maps crashing

My app crashes in the emulator when u load the map and then move the map and zoom in instantly. ive tried many different soulutions i found on the internet as the only error i get is Catastrophic Failure and no further information (no line number or any error information whatsoever)
C# code
public sealed partial class MapView : MvxWindowsPage
{
double lat=0;
double lon=0;
Geolocator gl = new Geolocator();
MapIcon Micon = new MapIcon();
Geopoint blo;
public MapView()
{
this.InitializeComponent();
Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
GetInitialPosition();
}
private MapViewModel ViewModel
{
get { return DataContext as MapViewModel; }
}
private bool HasViewModel { get { return ViewModel != null; } }
void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
{
e.Handled = true;
Windows.Phone.UI.Input.HardwareButtons.BackPressed -= HardwareButtons_BackPressed;
ViewModel.NavigateFirst();
}
async void GetInitialPosition()
{
gl.DesiredAccuracyInMeters = 500;
gl.DesiredAccuracy = PositionAccuracy.Default;
IAsyncOperation<Geoposition> locationTask = null;
try
{
Geoposition gp = await gl.GetGeopositionAsync(
maximumAge: TimeSpan.FromMinutes(5),
timeout: TimeSpan.FromSeconds(10)
);
//LatitudeTextBlock.Text = geoposition.Coordinate.Latitude.ToString("0.00");
//LongitudeTextBlock.Text = geoposition.Coordinate.Longitude.ToString("0.00");
}
finally
{
DispatcherTimer dt = new DispatcherTimer();
dt.Interval = new TimeSpan(0, 0, 5);
dt.Tick += (sender, e) => ProgBar.Visibility = Visibility.Collapsed;
dt.Tick += (sender, e) => ProgBar.IsEnabled = false;
dt.Start();
}
}
}
}
Xaml:
<views:MvxWindowsPage
xmlns:Maps="using:Windows.UI.Xaml.Controls.Maps"
x:Class="Etgarim.Views.MapView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Etgarim.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:views="using:Cirrious.MvvmCross.WindowsCommon.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Maps:MapControl x:Name="OmNaMap" MapServiceToken="..."/>
<!--Visibility="Visible" Center="{Binding blo}"-->
<ProgressBar x:Name="ProgBar" Height="667"/>
</Grid>
Move the map control and the progress bar so they not over lapping, this should resolve the issue.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="667"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<ProgressBar Grid.Row="0" x:Name="ProgBar" />
<Maps:MapControl Grid.Row="1" x:Name="OmNaMap" MapServiceToken="..."/>
<!--Visibility="Visible" Center="{Binding blo}"-->
</Grid>

WPF ComboBox Hide (Disable) DropDown Button Programmatically

I would like to know how to disable ComboBox DropDown Button Programmatically. I had seen many similar subjects but all of these have a XAML solution.
By the way, if someone know how to disable all ComboBox control design and left visible only item template it can be helpful too.
UPDATE
its my XAML definition
<ComboBox Name="lang_ComboBox" SelectionChanged="LanguageSelection_ComboBox_SelectionChanged"/>
And there is how i use it:
String text = "dorf";
BitmapImage image = new BitmapImage(new Uri("http://img88.imageshack.us/img88/4351/butchermi4.png"));
lang_ComboBox.Width = 100;
lang_ComboBox.Height = 30;
Grid sp;
for (int i = 0; i < 5; i++)
{
ColumnDefinition gridCol1 = new ColumnDefinition();
gridCol1.Width = new GridLength(30.0);
ColumnDefinition gridCol2 = new ColumnDefinition();
gridCol2.Width = new GridLength(70.0);
sp = new Grid()
{
Width = 100,
Height = 30
};
Image im = new Image()
{
Source = image,
Width = 25,
Height = 25
};
Label la = new Label()
{
Content = text
};
sp.ColumnDefinitions.Add(gridCol1);
sp.ColumnDefinitions.Add(gridCol2);
Grid.SetColumn(im, 0);
Grid.SetColumn(la, 1);
sp.Children.Add(la);
sp.Children.Add(im);
lang_ComboBox.Items.Add(sp);
}
UPDATE 2
Hmmm I get it now, I use wrong word. It should be "Hide" control design and still can choose from a list. My bad sorry. But i know how i can solve it with Anatoliy Nokolaev's Code. To hide control design i use:
ToggleButton dropDownButton = GetFirstChildOfType<ToggleButton>(lang_ComboBox);
dropDownButton.Visibility = System.Windows.Visibility.Collapsed;
Unwanted behavior is now only that i cant show combobox dropdownmenu, but I'll invoke it programmatically by add on click event and should be good.
If there is any easiest way to do this tell me :).
To disable only the ToggleButton in ComboBox programmatically, you need to find this in the ComboBox control using VisualTreeHelper and assign a property IsEnabled to false, like this:
XAML
<Window x:Class="DisableComboBoxButton.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"
Loaded="Window_Loaded">
<StackPanel>
<ComboBox Name="comboBox"
Width="100"
Height="25"
SelectedIndex="0">
<ComboBoxItem>Test1</ComboBoxItem>
<ComboBoxItem>Test2</ComboBoxItem>
<ComboBoxItem>Test3</ComboBoxItem>
</ComboBox>
<ComboBox Name="AllComboBoxDisabled"
Width="100"
Height="25"
IsEnabled="False"
SelectedIndex="0">
<ComboBoxItem>Test1</ComboBoxItem>
<ComboBoxItem>Test2</ComboBoxItem>
<ComboBoxItem>Test3</ComboBoxItem>
</ComboBox>
</StackPanel>
</Window>
Code-behind
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ToggleButton dropDownButton = GetFirstChildOfType<ToggleButton>(comboBox);
dropDownButton.IsEnabled = false;
}
public static T GetFirstChildOfType<T>(DependencyObject dependencyObject) where T : DependencyObject
{
if (dependencyObject == null)
{
return null;
}
for (var i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject); i++)
{
var child = VisualTreeHelper.GetChild(dependencyObject, i);
var result = (child as T) ?? GetFirstChildOfType<T>(child);
if (result != null)
{
return result;
}
}
return null;
}
}
Output
Notes
Always use GetFirstChildOfType() function only when the control will be fully loaded, otherwise it will not find it and give null. In this case, I put this code in the event Window_Loaded which says that all the controls of the Window successfully load.
Edit: another version
Not to say that this version is easier to implement, but it would be more correct and a bit easier to use.
So, we need a template for your ComboBox, because it allows access to elements that are within the control. Just like that, the ToggleButton can not be accessed from both the code and of XAML.
We create attached dependency property that will serve the current ComboBox another property, such as which will give access to our button Visibility.
Our property Visibility:
public static class ButtonExt
{
public static readonly DependencyProperty VisibilityProperty;
public static void SetVisibility(DependencyObject DepObject, Visibility value)
{
DepObject.SetValue(VisibilityProperty, value);
}
public static Visibility GetVisibility(DependencyObject DepObject)
{
return (Visibility)DepObject.GetValue(VisibilityProperty);
}
static ButtonExt()
{
PropertyMetadata VisibiltyPropertyMetadata = new PropertyMetadata(Visibility.Collapsed);
VisibilityProperty = DependencyProperty.RegisterAttached("Visibility",
typeof(Visibility),
typeof(ButtonExt),
VisibiltyPropertyMetadata);
}
}
Setter property in ComboBox template (skip version, full version see in project in App.xaml file):
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<ToggleButton Name="ToggleButton"
Template="{StaticResource ComboBoxToggleButton}"
IsChecked="{Binding Path=IsDropDownOpen,
Mode=TwoWay,
RelativeSource={RelativeSource TemplatedParent}}"
Visibility="{TemplateBinding PropertiesExtension:ButtonExt.Visibility}" // <------ Here
Grid.Column="2"
Focusable="False"
ClickMode="Press" />
Now, we are setting this property like this:
<ComboBox Name="comboBox"
Style="{StaticResource ComboBoxBaseStyle}"
PropertiesExtension:ButtonExt.Visibility="Visible"
Width="100"
Height="30"
SelectedIndex="0">
<ComboBoxItem>Test1</ComboBoxItem>
<ComboBoxItem>Test2</ComboBoxItem>
<ComboBoxItem>Test3</ComboBoxItem>
</ComboBox>
or in code-behind via Click event handlers:
private void HideButton_Click(object sender, RoutedEventArgs e)
{
ButtonExt.SetVisibility(comboBox, Visibility.Hidden);
}
private void ShowButton_Click(object sender, RoutedEventArgs e)
{
ButtonExt.SetVisibility(comboBox, Visibility.Visible);
}
Full version of example project is here.
Try with this
Dispatcher.BeginInvoke(new Action(() =>
{
ToggleButton dropDownButton = GetFirstChildOfType<ToggleButton>(cboMedicos);
if (dropDownButton != null)
{
dropDownButton.IsEnabled = false;
}
}), System.Windows.Threading.DispatcherPriority.Render);
public static T GetFirstChildOfType<T>(DependencyObject dependencyObject) where T : DependencyObject
{
if (dependencyObject == null)
{
return null;
}
for (var i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject); i++)
{
var child = VisualTreeHelper.GetChild(dependencyObject, i);
var result = (child as T) ?? GetFirstChildOfType<T>(child);
if (result != null)
{
return result;
}
}
return null;
}

Categories