What can I do if I want to have a text-box representing in real time the value of a loop counter in wpf?
appending working solution:
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private delegate void UpdateTextBox(DependencyProperty dp, Object value);
...
private void MyMethod()
{
...
int iMax=...;
...
MyClass iMyClass = new MyClass(arguments);
this.DataContext = iMyClass;
UpdateTextBox updateTBox = new UpdateTextBox(textBlock1.SetValue);
for (int i = 1; i <= iMax; i++)
{
iMyClass.MyClassMethod(i);
Dispatcher.Invoke(updateTBox, System.Windows.Threading.DispatcherPriority.Background, new object[] { MyClass.MyPropertyProperty, iMyClass.myProperty });
}
Here is the code I tried according to your suggestion, but it doesnt work, I get "0" written in the textbox, so I suppose the binding is OK, but the loop doesnt work. I also made the loop to write into another textbox directly by textbox2.text="a" inside the loop, but it didnt work either.
/// <summary>
/// Interaction logic for Window1.xaml
/// DOESNT WORK PROPERLY
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
TestClass tTest = new TestClass();
this.DataContext = tTest ;
tTest.StartLoop();
}
}
public class TestClass : DependencyObject
{
public TestClass()
{
bwLoop = new BackgroundWorker();
bwLoop.DoWork += (sender, args) =>
{
// do your loop here -- this happens in a separate thread
for (int i = 0; i < 10000; i++)
{
LoopCounter=i;
}
};
}
BackgroundWorker bwLoop;
public int LoopCounter
{
get { return (int)GetValue(LoopCounterProperty); }
set { SetValue(LoopCounterProperty, value); }
}
public static readonly DependencyProperty LoopCounterProperty = DependencyProperty.Register("LoopCounter", typeof(int), typeof(TestClass));
public void StartLoop()
{
bwLoop.RunWorkerAsync();
}
}
}
Run the loop in a background process (so that the UI can update itself while the loop is running) and
write the loop counter into a property (DependencyProperty or CLR property with INotifyPropertyChanged) which is bound to a TextBox in your user interface. Alternatively, you can directly change the value of the TextBox via Dispatcher.Invoke (this is less elegant, though).
Does this help? Feel free to ask for clarification...
Code example (untested), using a DependencyProperty (which must be bound to a TextBox):
BackgroundWorker bwLoop;
public static readonly DependencyProperty LoopCounterProperty =
DependencyProperty.Register("LoopCounter", typeof(int),
typeof(Window1), new FrameworkPropertyMetadata(0));
public int LoopCounter {
get { return (int)this.GetValue(LoopCounterProperty); }
set { this.SetValue(LoopCounterProperty, value); }
}
private MyWindow() {
...
bwLoop = new BackgroundWorker();
bwLoop.DoWork += (sender, args) => {
...
for (int i = 0; i < someLimit; i++) {
Dispatcher.Invoke(new Action(() => LoopCounter=i));
System.Threading.Thread.Sleep(250); // do your work here
}
}
bwLoop.RunWorkerCompleted += (sender, args) => {
if (args.Error != null)
MessageBox.Show(args.Error.ToString());
};
}
private void StartLoop() {
bwLoop.RunWorkerAsync();
}
you can use Data Binding for continuously updating the text.
Related
I build a simple ClipboardManager that hold all last Copy item.
So i have this simple ClipboardItem class:
public class ClipboardItem : INotifyPropertyChanged
{
private string _text { get; set; }
private int _index { get; set; }
public string Text
{
get { return _text; }
set
{
_text = value;
NotifyPropertyChanged();
}
}
public int Index
{
get { return _index; }
set
{
_index = value;
NotifyPropertyChanged();
}
}
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
And my ViewModel class that hold ObservableCollection<ClipboardItem>:
public class ViewModel : INotifyPropertyChanged
{
private ObservableCollection<ClipboardItem> _clipboards;
public ViewModel()
{
if (_clipboards == null)
{
_clipboards = new ObservableCollection<ClipboardItem>();
_clipboards.CollectionChanged += _clipboards_CollectionChanged;
}
}
private void _clipboards_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
for (int i = 0; i < _clipboards.Count; i++)
_clipboards[i].Index = i + 1;
}
public ObservableCollection<ClipboardItem> Clipboards
{
get { return _clipboards; }
set
{
_clipboards = value;
NotifyPropertyChanged();
}
}
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
So every Copy create new ClipboardItem object inside list but when i restart the application all the records gone so i wonder if there any way to store all my ClipboardItem object inside the application settings.settings file.
//Variable Creation
private string _dataFileName = #"ClipData.xml";
DataTable _clipDataTable = new DataTable();
Inside ViewModel constructor.
public ViewModel()
{
if (_clipboards == null)
{
_clipboards = new ObservableCollection<ClipboardItem>();
_clipboards.CollectionChanged += _clipboards_CollectionChanged;
}
InitDataTable();
ReadDataFile();
}
Create new Methods
/// <summary>
/// Initialize Data Table considering you have only 1 column data.
/// If you have more then you need to create more columns
/// </summary>
private void InitDataTable()
{
_clipDataTable = new DataTable();
_clipDataTable.Columns.Add("ClipHeader");
_clipDataTable.AcceptChanges();
}
//the clipboard Data is saved in xml file.
private void WriteDataFile()
{
DataSet ClipDataSet = new DataSet();
ClipDataSet.Tables.Add(_clipDataTable);
ClipDataSet.WriteXml(_dataFileName);
}
// if file exits then read the xml file and add it to the Collection, which will be reflected in UI.
private void ReadDataFile()
{
DataSet ClipDataSet = new DataSet();
if (File.Exists(_dataFileName))
{
ClipDataSet.ReadXml(_dataFileName);
foreach (DataRow item in ClipDataSet.Tables[0].Rows)
{
Clipboards.Add(new ClipboardItem { Text = Convert.ToString(item["ClipHeader"]) });
}
}
}
Using Command you can bind Method of ViewModel to Window Closing event. So whenever the user closes the window, the data in the collection will be written into the Xml file.
Data from the Collection is copied into DataTable.
private void WindowCloseCommadn(object o)
{
foreach (var item in Clipboards)
{
DataRow dataRow = _clipDataTable.NewRow();
dataRow["ClipHeader"] = item.Text;
_clipDataTable.Rows.Add(dataRow);
}
WriteDataFile();
}
Update:-
Same Code without ViewModel, by making the codebehind class has the DataContext for binding Collection.
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private ClipboardMonitor clipboardMonitor;
private string _dataFileName = #"ClipData.xml";
DataTable _clipDataTable = new DataTable();
public ObservableCollection<ClipboardItem> Clipboards { get; set; }
public MainWindow()
{
InitializeComponent();
Clipboards = new ObservableCollection<ClipboardItem>();
Clipboards.CollectionChanged += Clipboards_CollectionChanged;
Loaded += MainWindow_Loaded;
InitiateClipboardMonitor();
this.Closing += MainWindow_Closing1;
this.DataContext = this;
}
private void MainWindow_Closing1(object sender, CancelEventArgs e)
{
foreach (var item in Clipboards)
{
DataRow dataRow = _clipDataTable.NewRow();
dataRow["ClipHeader"] = item.Text;
_clipDataTable.Rows.Add(dataRow);
}
WriteDataFile();
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
InitDataTable();
ReadDataFile();
}
/// <summary>
/// Initialize Data Table considering you have only 1 column data.
/// If you have more then you need to create more columns
/// </summary>
private void InitDataTable()
{
_clipDataTable = new DataTable();
_clipDataTable.Columns.Add("ClipHeader");
_clipDataTable.AcceptChanges();
}
private void WriteDataFile()
{
DataSet ClipDataSet = new DataSet();
ClipDataSet.Tables.Add(_clipDataTable);
ClipDataSet.WriteXml(_dataFileName);
}
private void ReadDataFile()
{
DataSet ClipDataSet = new DataSet();
if (File.Exists(_dataFileName))
{
ClipDataSet.ReadXml(_dataFileName);
foreach (DataRow item in ClipDataSet.Tables[0].Rows)
{
Clipboards.Add(new ClipboardItem { Text = Convert.ToString(item["ClipHeader"]) });
}
}
}
private void Clipboards_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
for (int i = 0; i < Clipboards.Count; i++)
{
Clipboards[i].Index = i + 1;
}
}
private void InitiateClipboardMonitor()
{
clipboardMonitor = new ClipboardMonitor();
clipboardMonitor.OnClipboardContentChanged += ClipboardMonitor_OnClipboardContentChanged; ;
}
private void ClipboardMonitor_OnClipboardContentChanged(object sender, EventArgs e)
{
string clipboardText = Clipboard.GetText(TextDataFormat.Text);
Clipboards.Add(new ClipboardItem { Text = clipboardText });
}
}
to know about Command, refer the article
https://www.codeproject.com/Articles/274982/Commands-in-MVVM
I've tried to find a solution myself but I was not able, for some reason the DataContext is not correctly set up in the usercontrol's viewmodel
The idea is to have a single usercontrol that permits to perform a query on a fixed collection and allows the user to drop a treeviewitem that holds an item of the collection (in case the user have the treeview open)
In my main view I've defined :
<views:PortfolioChooserView x:Name="PortfolioChooserView" DataContext="{Binding PortfolioCompleteBox}" Height="25" LoadDefaultValue="True" />
Where PortfolioCompleteBox is a ViewModel defined in the MainViewModel as
public PortfolioChooserViewModel PortfolioCompleteBox
{
get { return GetValue<PortfolioChooserViewModel>(PortfolioChooserViewModelProperty); }
set { SetValue(PortfolioChooserViewModelProperty, value); }
}
public static readonly PropertyData PortfolioChooserViewModelProperty = RegisterProperty("PortfolioCompleteBox", typeof(PortfolioChooserViewModel));
public MainViewModel(ICreditLimitRepository creditLimitRepository, IDynamicContainer dynamicContainer)
{
this.creditLimitRepository = creditLimitRepository;
this.dynamicContainer = dynamicContainer;
LoadCreditLimitsCommand = new Command<object>(OnLoadCreditLimitsExecute, (() => OnLoadCreditLimitsCanExecute));
var viewModelFactory = this.GetServiceLocator().ResolveType<IViewModelFactory>();
PortfolioCompleteBox = viewModelFactory.CreateViewModel<PortfolioChooserViewModel>(null);
Model = new FiltersLoadModel();
}
My problem is that on the PortFolioChooserView I've the DataContext set to null (and I got 2 calls to the PortFolioChooserViewModel, one from the MainViewModel and the other one from the PortFolioChooserView's viewmodel locator)
public partial class PortfolioChooserView
{
private PortfolioChooserViewModel viewModel;
readonly bool isFirstLoad = true;
/// <summary>
/// Initializes a new instance of the <see cref="PortfolioChooserView"/> class.
/// </summary>
///
public PortfolioChooserView()
{
InitializeComponent();
if (isFirstLoad)
{
PortfolioCompleteBox.AllowDrop = true;
DragDropManager.AddPreviewDragOverHandler(PortfolioCompleteBox, OnElementDragOver);
DragDropManager.AddDropHandler(PortfolioCompleteBox, OnElementDrop);
isFirstLoad = false;
this.Loaded += PortfolioChooserView_Loaded;
this.DataContextChanged += PortfolioChooserView_DataContextChanged;
}
}
void PortfolioChooserView_DataContextChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e)
{
int t = 0;
}
void PortfolioChooserView_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
viewModel = (PortfolioChooserViewModel)this.DataContext;
}
private void OnElementDragOver(object sender, Telerik.Windows.DragDrop.DragEventArgs e)
{
var options = Telerik.Windows.DragDrop.DragDropPayloadManager.GetDataFromObject(e.Data, TreeViewDragDropOptions.Key) as TreeViewDragDropOptions;
if (options != null)
{
var visual = options.DragVisual as TreeViewDragVisual;
if (visual != null) visual.IsDropPossible = true;
}
e.Handled = true;
}
private void OnElementDrop(object sender, Telerik.Windows.DragDrop.DragEventArgs e)
{
var context = ((IPortfolioAutoComplete)this.DataContext);
context.SetPortfolioAutoCompleteBox(e);
}
public static readonly DependencyProperty LoadDefaultValueProperty = DependencyProperty.Register(
"LoadDefaultValue", typeof(bool), typeof(PortfolioChooserView), new PropertyMetadata(default(bool)));
public bool LoadDefaultValue
{
get { return (bool)GetValue(LoadDefaultValueProperty); }
set { SetValue(LoadDefaultValueProperty, value); }
}
}
What am I doing wrong?
Thanks
Don't try to manage your own vm's
Catel will automatically accept a parent-vm as it's own vm as long as they are compatible. You don't need to handle this manually in your view loading in the view.
Instead of creating a VM in the parent VM, use a model only (so the vm only cares about what the VM itself should do). Then set the DC of the PortfolioChooserView to the model. Then the vm of the child view can accept the model in the ctor and be managed on it's own.
There are much better ways to communicate between vm's then trying to micro-manage like you are doing now. As always, see the docs.
I need to know, if the SelectedItems got filled when Ctrl or Shift was pressed or not. Is there an easy way (without creating a new controltemplate) to get this info? I prefer solutions without code behind.
Best regards
Yannik
You can wire up selection changed event, and check if Modifier Keys are pressed for Selection.
void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var isCtrlorShiftDown = (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl) || Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift));
if (isCtrlorShiftDown)
{
// Write your Logic Here;
}
}
I found a solution with minimal code behind.
The main concept is, that I attach to KeyDown and KeyUp events in the MainWindow and set a property "CurrentKeyboardKeyPressed" on the MainViewModel, which propagates the pressed key info to the child view models, which in turn fire a custom event with a special Selection class that has the currently pressed key info.
The posted source code is heavyli shortened and does not run at all. If somebody is interested in the working solution, just ask me and I will email it.
MainWindow.xaml.cs
public partial class MainWindow : Window
{
private readonly MainWindowViewModel _mainWindowViewModel;
public MainWindow()
{
_mainWindowViewModel = new MainWindowViewModel();
InitializeComponent();
DataContext = _mainWindowViewModel;
}
private void MainWindow_OnKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl)
{
_mainWindowViewModel.CurrentKeyboardKeyPressed = PressedKeyboardKey.Ctrl;
return;
}
if (e.Key == Key.LeftShift || e.Key == Key.RightShift)
{
_mainWindowViewModel.CurrentKeyboardKeyPressed = PressedKeyboardKey.Shift;
}
}
private void MainWindow_OnKeyUp(object sender, KeyEventArgs e)
{
_mainWindowViewModel.CurrentKeyboardKeyPressed = PressedKeyboardKey.None;
}
}
MainWindowViewModel.cs
public class MainWindowViewModel : ViewModelBase
{
// child view models
private readonly ObservableCollection<TTSViewModel> _ttsViewModels;
private PressedKeyboardKey _currentKeyboardKeyPressed;
public EventHandler<KeyboardKeyPressedEventArgs> CurrentKeyboardKeyPressedChanged;
public MainWindowViewModel()
{
_ttsViewModels = new ObservableCollection<TTSViewModel>();
}
public PressedKeyboardKey CurrentKeyboardKeyPressed
{
get { return _currentKeyboardKeyPressed; }
set
{
if (_currentKeyboardKeyPressed != value)
{
_currentKeyboardKeyPressed = value;
OnCurrentKeyboardKeyPressedChanged(_currentKeyboardKeyPressed);
}
}
}
// create child view models
public void PopulateTTSList(int itemsToCreated)
{
for (int i = 0; i < itemsToCreated; i++)
{
var tts = new TTSViewModel("TTS " + i);
tts.FractionSelectionChanged += OnTTSFractionSelectionChanged;
CurrentKeyboardKeyPressedChanged += tts.CurrentKeyboardKeyPressedChanged;
_ttsViewModels.Add(tts);
}
}
private void OnCurrentKeyboardKeyPressedChanged(PressedKeyboardKey currentKeyboardKeyPressed)
{
var handler = CurrentKeyboardKeyPressedChanged;
if (handler != null)
{
handler(this, new KeyboardKeyPressedEventArgs(currentKeyboardKeyPressed));
}
}
// selection changed handler for each child view model
private void OnTTSFractionSelectionChanged(object sender, ItemSelectionChangedEventArgs fractionSelectionChangedEventArgs)
{
var sendingTTS = sender as TTSViewModel;
if (fractionSelectionChangedEventArgs.Selection.PressedKeyOnSelection == PressedKeyboardKey.None)
{
// single selection action goes here
// ....
}
else
{
// multi selection action goes here
// ....
}
}
}
TTSViewModel.cs (child view model)
public class TTSViewModel : ViewModelBase
{
private readonly SmartObservableCollection<FractionViewModel> _currentlySelectedfractions;
public EventHandler<ItemSelectionChangedEventArgs> FractionSelectionChanged;
private PressedKeyboardKey _currentKeyboardKeyPressed;
public TTSViewModel()
{
_currentlySelectedfractions = new SmartObservableCollection<FractionViewModel>();
_currentlySelectedfractions.CollectionChanged += CurrentlySelectedfractionsOnCollectionChanged;
}
public void CurrentKeyboardKeyPressedChanged(object sender, KeyboardKeyPressedEventArgs currentKeyboardKeyPressedEventArgs)
{
_currentKeyboardKeyPressed = currentKeyboardKeyPressedEventArgs.CurrentKeyboardKeyPressed;
}
private void CurrentlySelectedfractionsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
{
if (FractionSelectionChanged != null)
{
if (notifyCollectionChangedEventArgs.Action == NotifyCollectionChangedAction.Replace && notifyCollectionChangedEventArgs.NewItems != null)
{
var removed = _oldSelectedfractions.Except(_currentlySelectedfractions);
var added = _currentlySelectedfractions.Except(_oldSelectedfractions);
var selection = new Selection<FractionViewModel>(added, removed, _currentKeyboardKeyPressed);
_oldSelectedfractions.Clear();
foreach (var currentlySelectedfraction in _currentlySelectedfractions)
{
_oldSelectedfractions.Add(currentlySelectedfraction);
}
var selectionChangedArgs = new ItemSelectionChangedEventArgs(selection);
FractionSelectionChanged(this, selectionChangedArgs);
}
}
}
}
Selection.cs
public sealed class Selection<T>
{
private readonly List<T> _added;
private readonly List<T> _removed;
private readonly PressedKeyboardKey _currentKeyboardKeyPressed;
public Selection()
{
_added = new List<T>();
_removed = new List<T>();
}
/// <summary>
/// Initializes a new instance of the <see cref="Selection{T}" /> class.
/// </summary>
/// <param name="addedItems">[NotNull]</param>
/// <param name="removedItems">[NotNull]</param>
/// <param name="currentKeyboardKeyPressed">The current keyboard key pressed.</param>
public Selection(IEnumerable<T> addedItems, IEnumerable<T> removedItems, PressedKeyboardKey currentKeyboardKeyPressed)
: this()
{
_added.AddRange(addedItems);
_removed.AddRange(removedItems);
_currentKeyboardKeyPressed = currentKeyboardKeyPressed;
}
public IReadOnlyList<T> Added
{
get { return _added; }
}
public IReadOnlyList<T> Removed
{
get { return _removed; }
}
public PressedKeyboardKey PressedKeyOnSelection
{
get { return _currentKeyboardKeyPressed; }
}
}
KeyboardKeyPressedEventArgs.cs
public sealed class KeyboardKeyPressedEventArgs : EventArgs
{
public KeyboardKeyPressedEventArgs(PressedKeyboardKey currentKeyboardKeyPressed)
{
CurrentKeyboardKeyPressed = currentKeyboardKeyPressed;
}
public PressedKeyboardKey CurrentKeyboardKeyPressed { get; private set; }
}
ItemSelectionChangedEventArgs.cs
public sealed class ItemSelectionChangedEventArgs : EventArgs
{
public ItemSelectionChangedEventArgs(Selection<FractionViewModel> newSelection)
{
Selection = newSelection;
}
public Selection<FractionViewModel> Selection { get; private set; }
}
PressedKeyboardKey.cs
public enum PressedKeyboardKey
{
None,
Ctrl,
Shift
}
I have a simple search text box. This text box acts as a filter. I've now copied/pasted the code for the 5th time and enough is enough. Time for a custom control.
left and right brackets have been replaced with ()
My custom control will be simple. My problem is I want to have a dependencyProperty on this control that is of type List(T).
I created a test project to proof it out and make sure it works. It works well. Ignore List.
Below is the entire class. The problem is that the only thing holding me up is replacing List (Person) with List(T). Something like List where: T is Object
typeof(List(T) where: T is Object) <= Obviously I can't do that but gives an idea what I'm trying to accomplish.
public class SearchTextBox : TextBox
{
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register("FilterSource", typeof(List<Person>), typeof(SearchTextBox), new UIPropertyMetadata(null)); //I WANT THIS TO BE LIST<T>
public List<Person> FilterSource
{
get
{
return (List<Person>)GetValue(SourceProperty);
}
set
{
SetValue(SourceProperty, value);
}
}
public static readonly DependencyProperty FilterPropertyNameProperty =
DependencyProperty.Register("FilterPropertyName", typeof(String), typeof(SearchTextBox), new UIPropertyMetadata());
public String FilterPropertyName
{
get
{
return (String)GetValue(FilterPropertyNameProperty);
}
set
{
SetValue(FilterPropertyNameProperty, value);
}
}
public SearchTextBox()
{
this.KeyUp += new System.Windows.Input.KeyEventHandler(SearchBox_KeyUp);
}
void SearchBox_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
ICollectionView view = CollectionViewSource.GetDefaultView(FilterSource);
view.Filter = null;
view.Filter = new Predicate<object>(FilterTheSource);
}
bool FilterTheSource(object obj)
{
if (obj == null) return false;
Type t = obj.GetType();
PropertyInfo pi = t.GetProperty(FilterPropertyName);
//object o = obj.GetType().GetProperty(FilterPropertyName);
String propertyValue = obj.GetType().GetProperty(FilterPropertyName).GetValue(obj, null).ToString().ToLower();
if (propertyValue.Contains(this.Text.ToLower()))
{
return true;
}
return false;
}
}
No; that's not possible.
Instead, just use the non-generic typeof(IList).
If two Window is opened mainly A and B, how to close Window A using code that written on Window B.
Your best bet would be to create a property on Window B that you pass the creating Window to. Something like this. I have a Window named MainWindow and a second Window named Window2.
Main Window
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Window2 secondForm;
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
secondForm = new Window2();
secondForm.setCreatingForm =this;
secondForm.Show();
}
}
}
Window2
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for Window2.xaml
/// </summary>
public partial class Window2 : Window
{
Window creatingForm;
public Window2()
{
InitializeComponent();
}
public Window setCreatingForm
{
get { return creatingForm; }
set { creatingForm = value; }
}
private void button1_Click(object sender, RoutedEventArgs e)
{
if (creatingForm != null)
creatingForm.Close();
}
}
}
In respose to your comment, closing a window that was created by another form is as easy as calling the Close Method of the created Form:
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Window2 secondForm;
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
if (secondForm == null)
{
secondForm = new Window2();
secondForm.Show();
}
else
secondForm.Activate();
}
private void button2_Click(object sender, RoutedEventArgs e)
{
if (secondForm != null)
{
secondForm.Close();
secondForm = new Window2();
//How ever you are passing information to the secondWindow
secondForm.Show();
}
}
}
}
Here is a way to close any window from any other window. You can modify it to work with multiple instances by giving your windows some unique identifier and then just searching for that in the foreach loop.
public static class Helper
{
public static void CloseWindowOfWhichThereIsOnlyOne<T>()
{
Assembly currentAssembly = Assembly.GetExecutingAssembly();
foreach (Window w in Application.Current.Windows)
{
if (w.GetType().Assembly == currentAssembly && w is T)
{
w.Close();
break;
}
}
}
}
Or with a unique identifier "fudge":
public static void CloseWIndowUsingIdentifier(string windowTag)
{
Assembly currentAssembly = Assembly.GetExecutingAssembly();
foreach (Window w in Application.Current.Windows)
{
if (w.GetType().Assembly == currentAssembly && w.Tag.Equals(windowTag))
{
w.Close();
break;
}
}
}
I like this better than the suggested solution because you don't need to mess with your windows, other than to give them unique tags. I've only been using this for small projects where there is no risk of things not being unique, I'm not going to lose track of 10-12 windows!
The other suggested solution is a little silly (I don't have 50 karma to comment on it) as you could just call win.close() if you already had a reference to the object...
it is very simple make one public class and method like this
class Helper
{
public static void CloseWindow(Window x)
{
Assembly currentAssembly = Assembly.GetExecutingAssembly();
// int count = Application.Current.Windows;
foreach (Window w in Application.Current.Windows)
{
//Form f = Application.OpenForms[i];
if (w.GetType().Assembly == currentAssembly && w==x)
{
w.Close();
}
}
}
}
now call this function from where you want close window like this .
Helper.CloseWindow(win);//win is object of window which you want to close.
hope this helps.
foreach (Window w in Application.Current.Windows)
{
if (w.Name != "Main_Window_wind" )
{
w.Visibility = System.Windows.Visibility.Hidden;
}
}
//name is the x:Name="Main_Window_wind" in xaml
You can close now as hiden all windows without closing the named Main_Window_wind , you can add another window to be not closed with this in if: w.Name != "Main_Window_wind" && w.Name != "AnyOther_Window_wind" &&...
a quicker way is this:
for (int intCounter = App.Current.Windows.Count - 1; intCounter > -1; intCounter--)
{
if (App.Current.Windows[intCounter].Name != "Main_Window_wind")
App.Current.Windows[intCounter].Visibility = System.Windows.Visibility.Hidden;
}