I have a window with a button in it, and I need to remove it OR not depending on the argument passed to the window:
public MainWindow(bool removeControl)
{
InitializeComponent();
if (removeControl)
{
//code to remove the button
}
}
In the XAML file I declare a normal button:
<Button Width="120" Height="25" Content="Click" Name="ClickButton"></Button>
I know this can be done by doing the reverse thing which means add the button depending of the Boolean parameter, but I need to do so.
You can do:
mybutton.Visibility = Visibility.Collapsed;
...or if you really want it to be removed from the "logical tree"...then it all depends what "container"/parent that Button is in, in how you remove it.
Disconnecting an element from any/unspecified parent container in WPF
Remove Control from Window in WPF
http://joe-bq-wang.iteye.com/blog/1613370
Related
I'm developing an WPF using MVVM pattern, C# and .NET Framework 4.6.1.
I have a Window that contains an UserControl (Control1) and that UserControl contains another UserControl (Control2). I have chosen this way to do it instead of using a Dialog Window (Control2 acts as Dialog Window).
Both user controls have a Viewmodel (Control1VM and Control2VM).
I use Control2 as a form to let users input some data that I need to start the application.
This is the MainWindow with Control1:
And this is Control2 over Control1.
My problem is that I don't know how to hide Control2 when I click on OK or Cancel button.
This is how Control2 is set on Control1:
<Grid x:Name="gridControl2" Margin="30" Grid.RowSpan="6" Grid.ColumnSpan="3" Visibility="{Binding GridControl2Visibility}">
<local:Control2 x:Name="userControlControl2" />
</Grid>
To show Control2 and set GridControl2Visibility to Visible in Control1VM:
public Visibility GridControl2Visibility
{
get { return gridControl2Visibility; }
set
{
if (gridControl2Visibility != value)
{
gridControl2Visibility = value;
RaisePropertyChangedEvent("GridControl2Visibility");
}
}
}
How can I hide Control2 when I click on Ok or Cancel button in Control2? My problem is that GridControl2Visibility is on Control1VM and I can't access that class from Control2VM.
Use a service that both view models can access and that stores the info whether Control2 should be visible or not. Ideally, the service would be registered as singleton with your di-container and injected into the view models.
Alternatively, you can use an event aggregator, which is basically a singleton service, too, but focused on distributing events rather than holding a state.
You can use events, You can raise event from Control2VM and hadnle it in Control1VM and set GridControl2Visibility to false.
Background:
I have an application that has list of CheckBoxes and Button.
If the user selects a (or multiple) CheckBox and Click on the button, the Button event handler checks which CheckBox is checked. Based on that, it runs a process (ie. gpupate).
Then, I have an image (Visibility = "hidden") next to CheckBox in XAML. After the button is clicked, the code behind sets it to Visibility.Visible.
After the process is done, the Source of the image is changed to a different image. Bascically, the first image shows the process is running, second image is a check showing its completed.
I am trying to implement INotifyPropertyChanged Interface, so the UI is updated automatically after I change the visibility. Sometimes, UI is not updated after the the visibility is changed because there are number of CheckBoxes.
However, since I am not using any property, I cannot really bind it to something (or may be I am missing something) and INPC interface.
How can I implement the interface (or similar functionality).
XAML Code
<StackPanel Orientation="Horizontal">
<Image x:Name="oneImage"
Source="{StaticResource inProcessImage}"
Visibility="Hidden" />
<CheckBox x:Name="oneCheckBox"
Content="CheckBox"
Style="{StaticResource normalCheckBox}"/>
</StackPanel>
Code Behind inside Button Event Handler
if (oneCheckBox.IsChecked ?? false)
{
oneImage.Visibility = Visibility.Visible;
await Task.Run(() =>
{
//run GPUpdate
});
deleteHistoryImage.Source = (ImageSource)Resources["doneCheckImage"];
}
I do not have anything regarding the implementation of interface because I do not know what do I need to bind Visibility modifier with.
This is not what you're looking for, but it will update the GUI manually.
public void UpdateUI()
{
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { }));
}
call UpdateUI(); after you change the visibility.
Lets say I have a xaml file, a window, why not. in this xaml I have a grid with multiple labels, textBoxs, comboBoxs, lists... You see the patern. At a certain point (where X == true for say) I want to be able to catch a click inside the grid and everything in it.
I want to be still able to do what this click was going to do so a full-filled Rect over the grid is not the answer I'm looking for. The action of the click would be to put X back to false. nothing much.
Is there an easy way to manage a click on a grid and everything inside it?
Thanks in advance
You just need to use an event that is common to all of the controls. Probably the best one for this scenario is the UIElement.PreviewMouseDown event. Try this:
<StackPanel UIElement.PreviewMouseDown="StackPanel_PreviewMouseDown">
<Label Content="I'm a Label" />
<Button Content="I'm a Button" />
<CheckBox Content="I'm a CheckBox" />
</StackPanel>
You need to use one of the Preview... events so that you can catch it before the Buttons consume it... the UIElement.MouseDown event wouldn't work with Buttons for that very reason. However, you can use the othwer Preview... methods, like the UIElement.PreviewLeftMouseButtonDown event, for example.
Can you give your sample code?
From my understanding,you can use this,it will capture all your click inside grid.
.xaml
<Grid MouseDown="Grid_MouseDown">
<Label MouseDown="Grid_MouseDown" />
<Button MouseDown="Grid_MouseDown"/>
<Button MouseDown="Grid_MouseDown"/>
</Grid>
.xaml.cs
private Grid_MouseDown(object sender,MouseButtonEventArgs e)
{
if(X==true)
{
//doSomething
}
else
{
//do SomethingElse
}
}
edit: How about this?
I have a class MyWindow which inherits from Window. Within MyWindow, I have the following method to execute once my OK button is clicked:
private void OKButton_Click(object sender, RoutedEventArgs e)
{
var be = NameBox.GetBindingExpression(TextBox.TextProperty);
be.UpdateSource();
this.Close();
}
XAML:
<Button Content="OK"
Click="OKButton_Click"
HorizontalAlignment="Left"
Margin="175,473,0,0"
VerticalAlignment="Top"
Width="75"
RenderTransformOrigin="-0.04,0.5"/>
In a separate class where I initialize my UI window, I say
MainWindow window = new MainWindow(ViewModel);
window.Show();
However, as soon as window.Show() is executed, the subsequent code is executed and I cannot actually interact with my window to do what I need to do. I feel like this is just a misunderstanding in how to actually use WPF in a larger context...any help?
Window.ShowDialog is what is needed to view the page. But one doesn't get the binding information as you did; which should be changed as well.
When the textbox loses focus it will update the binding so the code
var be = NameBox.GetBindingExpression(TextBox.TextProperty);
be.UpdateSource();
is not needed. (Is this a leftover form winform programming?) So I suggestion one not update a binding as such.
The only possible thing to do if the binding is not updated is to change the binding to use the mode of TwoWay which ensures a back and forth data transfer between the variable bound to and the textbox on the screen.
This is a tough question, but I'll try to explain anyway...
I have a custom control window that is used all over my applicaton. The reason I did this is because I wanted the various windows and dialog boxes to be fully customizable across my program. I.e., the minimize, maximize, close button and frame are all custom. This window is templated inside my generic.xaml. Now this works and it's all good. The idea I got was from http://www.codeproject.com/KB/WPF/CustomFrames.aspx
Now the users of this custom window are user controls in their xaml they basically use MyWindow as their root element:
<MyWindow>
....
</MyWindow>
But now what I'm trying to do is "inject" certain elements into MyWindow from the User Control's xaml. MyWindow would simply have a container for hosting them. For example, they might want to inject a toolbar button that appears right next to the minimize button. So for example, I might have a user control that does the following (where MyWindow is the root element):
<MyWindow>
<MyWindow.ToolBar>
<Button x:Name="BlaBla"/>
</MyWindow.ToolBar>
</MyWindow>
This would put "blabla" right next to the minimize button for example. But I'm wondering if it's even possible to do this. I.e., the whole MyWindow.ToolBar thing. Is there a construct for this, is this an attached property or something weirder?
It definitely is possible, depends on your choice of types for the DependencyProperty. You could use IEnumerable and bind the MyWindow.ToolBar dp to the ItemsSource on your internal ToolBar.
<ControlTemplate>
<!-- ... snipped down to the ToolBar ... -->
<ToolBarTray>
<ToolBar x:Name="PART_ToolBar" />
</ToolBarTray>
</ControlTemplate>
With the appropriate code in OnApplyTemplate to pull PART_ToolBar and create new Binding for the ItemsSource.
EDIT: rereading your question it appears that I missed that you wanted to add this elsewhere. My suggestion then would be to use this as an object dependency property, with a ContentPresenter bound to the MyWindow.ToolBar with a Visibility set if the binding is not {x:Null}.