Proportional sizing in wpf - wpf

I have a Grid having two columns. One column is twice the width as other.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="12"/>
<TextBox Grid.Column="1" Text="" />
</Grid>
But during runtime when i type in second text box the width changes without maintaining the 1:2 ratio.
I dont want to keep fixed width. The width will be changed at runtime based on user entry.
I want the width to be in 1:2 ratio even if the width changes at runtime?

Here is another, alternative answer that you can modify into your needs.
In this example, you can enter the width of your grid in the textbox in the first column. Or you can expand or decrease the width with the button. Just for illustration. You may have to change this for your purpose.
MainWindow.cs
public partial class MainWindow : Window, INotifyPropertyChanged
{
public static readonly DependencyProperty GridWidthProperty = DependencyProperty.Register("GridWidth", typeof(Double), typeof(MainWindow), new UIPropertyMetadata(300d, OnGridWidthPropertyChanged));
public Double GridWidth
{
get { return (Double)GetValue(GridWidthProperty); }
set
{
SetValue(GridWidthProperty, value);
NotifyPropertyChanged("GridWidth");
}
}
public static readonly DependencyProperty ColumnWidthProperty = DependencyProperty.Register("ColumnWidth", typeof(String), typeof(MainWindow), new UIPropertyMetadata("100", OnColumnWidthPropertyChanged));
public String ColumnWidth
{
get { return (String)GetValue(ColumnWidthProperty); }
set
{
SetValue(ColumnWidthProperty, value);
NotifyPropertyChanged("ColumnWidth");
}
}
private static void OnGridWidthPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
MainWindow ctl = sender as MainWindow;
ctl.doGridWidthChanged();
ctl = null;
}
private static void OnColumnWidthPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
MainWindow ctl = sender as MainWindow;
ctl.doColumnWidthChanged();
ctl = null;
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
}
private void button_Click(object sender, RoutedEventArgs e)
{
if (sender == button1)
this.GridWidth += 50;
else if (sender == button2)
this.GridWidth -= 50;
}
private void doGridWidthChanged()
{
if (Double.IsNaN(this.GridWidth))
return;
this.ColumnWidth = Math.Round((this.GridWidth / 3), 2).ToString();
}
private void doColumnWidthChanged()
{
Double columnwidthval = Double.NaN;
if (!String.IsNullOrEmpty(this.ColumnWidth) && Double.TryParse(this.ColumnWidth, out columnwidthval))
this.GridWidth = columnwidthval * 3;
else
this.ColumnWidth = Math.Round((this.GridWidth / 3), 2).ToString();
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(String PropertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
}
}
And here is my XAML code.
MainWindow.xaml
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication3"
Title="MainWindow" Height="600" Width="800">
<Grid>
<Grid Margin="0,60,0,0"
Width="{Binding Path=GridWidth}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Background="GhostWhite" />
<Border Grid.Column="1" Background="AliceBlue" />
<Border Grid.ColumnSpan="2" BorderBrush="DimGray" BorderThickness="1" />
<StackPanel Grid.Column="0" Orientation="Vertical" Margin="3">
<TextBlock Text="Single" />
<TextBox Text="{Binding Path=ColumnWidth, Mode=TwoWay}" />
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Vertical" Margin="3">
<TextBlock Text="Double" />
</StackPanel>
</Grid>
<Button Content="Increase" Height="34" HorizontalAlignment="Left" Margin="19,12,0,0" Name="button1" VerticalAlignment="Top" Width="90" Click="button_Click" />
<Button Content="Decrease" Height="34" HorizontalAlignment="Left" Margin="120,12,0,0" Name="button2" VerticalAlignment="Top" Width="90" Click="button_Click" />
</Grid>
</Window>
Hope that helps!

This can be done like this:
MainWindow.xaml
<Grid>
<Grid Width="{Binding Path=GridWidth}"
Margin="0,60,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="Single 33%"/>
<TextBox Grid.Column="1" Text="Double 67%" />
</Grid>
<Button Content="Increase" Height="34" HorizontalAlignment="Left" Margin="19,12,0,0" Name="button1" VerticalAlignment="Top" Width="90" Click="button_Click" />
<Button Content="Decrease" Height="34" HorizontalAlignment="Left" Margin="120,12,0,0" Name="button2" VerticalAlignment="Top" Width="90" Click="button_Click" />
</Grid>
I have two buttons that increase or decrease the total grid width for illustration.
MainWindows.cs
public partial class MainWindow : Window, INotifyPropertyChanged
{
public static readonly DependencyProperty GridWidthProperty = DependencyProperty.Register("GridWidth", typeof(Double), typeof(MainWindow), new UIPropertyMetadata(300d));
public Double GridWidth
{
get { return (Double)GetValue(GridWidthProperty); }
set
{
SetValue(GridWidthProperty, value);
NotifyPropertyChanged("GridWidth");
}
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
}
private void button_Click(object sender, RoutedEventArgs e)
{
if (sender == button1)
this.GridWidth += 50;
else if (sender == button2)
this.GridWidth -= 50;
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(String PropertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
}
}

Related

How to bind CheckBoxes to a bidimensional array in WPF?

I'm new to WPF, so please be patient with me. I have a bidimensional int array (8x8), a uniform grid (8 rows and 8 columns). In each cell of my grid there is a CheckBox. When I click on a checkbox I wish that the corresponding element in my array to change from "0" to "1". When I uncheck again the CheckBox, I wish that this change be reflected in my array.
Further, I will take each row from in my int[8,8] matrix (for example 10010101 - first checkbox in the uniform grid is checked, the second is not checked and so on), convert it to a decimal number and send it over the serial port when I click a button.
Then I want to change the sending process ( process all 8 rows and send the data) in such way that it takes place every time I click on a checkbox from my grid.
I'm stucked with the Bindings.
I hope someone can give me an advice on how should I to do this.
This is my XAML code. Somehow I succeeded to make a binding for my first CheckBox but I'm not understanding well why it's working and If I did the best coding. If I continue in this way I should create a property for every element in my array and I'm sure this is not the right way to do it (because I hardcoded data[0,0]).
<Window x:Class="CheckBox_Matrix_Binding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="220" Width="200" ResizeMode="NoResize" >
<Grid x:Name="mainGrid">
<Grid.RowDefinitions>
<RowDefinition Height="4*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<UniformGrid x:Name="checkBoxGrid" Grid.Row="0" Rows="3" Columns="3" >
<CheckBox x:Name="ChekBox0" HorizontalAlignment="Center" VerticalAlignment="Center" IsChecked="{Binding Mode=TwoWay, Path=DataProperty}" />
<CheckBox x:Name="ChekBox1" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<CheckBox x:Name="ChekBox2" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<CheckBox x:Name="ChekBox3" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<CheckBox x:Name="ChekBox4" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<CheckBox x:Name="ChekBox5" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<CheckBox x:Name="ChekBox6" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<CheckBox x:Name="ChekBox7" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<CheckBox x:Name="ChekBox8" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</UniformGrid>
<Grid Grid.Row="1" x:Name="buttonsGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="btnSetTrue" VerticalAlignment="Center" Grid.Column="0" Content="Set _True" Margin="5" Click="btnSetTrue_Click" ></Button>
<Button x:Name="btnSetFalse" VerticalAlignment="Center" Grid.Column="1" Content="Set _False" Margin="5" Click="btnSetFalse_Click" ></Button>
</Grid>
</Grid>
</Window>
This is my code behind:
using System;
using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;
namespace CheckBox_Matrix_Binding
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private DataMatrix _dataMatrix = new DataMatrix() ;
public bool _DataMatrixProperty
{
get { return _dataMatrix.DataProperty; }
set
{
_dataMatrix.DataProperty = value;
}
}
public MainWindow()
{
InitializeComponent();
checkBoxGrid.DataContext = _dataMatrix;
}
private void ChekBox0_Checked(object sender, RoutedEventArgs e)
{
}
private void btnSetTrue_Click(object sender, RoutedEventArgs e)
{
_dataMatrix.DataProperty = true;
}
private void btnSetFalse_Click(object sender, RoutedEventArgs e)
{
_dataMatrix.DataProperty = false;
}
}
//THe class DataMatrix implements INotifyPropertyChanged interface
public class DataMatrix: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool[,] data;
public bool DataProperty //this is a property
{
get { return data[0, 0]; }
set {
data[0, 0] = value;
OnPropertyChanged("DataProperty");
}
}
public DataMatrix()
{
data = new bool[3, 3];
}
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
Should I use another approach?
Thankyou in advance :)

How I can print listbox item count along with Expander header?

I want to print listbox item count alog with header of expander like
header1 (count) . How can I achieve this in WPF
You haven't provided any code for what you have done, such as if you are using a ViewModel or doing code-behind. There are multiple ways to go about it.
My ViewModel Way
In this example, I've made a ViewModel containing an ObservableCollection of string to populate the ListBox. The Expander header is bound to a property that is populated using a combination of the HeaderText and ItemCount.
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _headerText = string.Empty;
private string _headerTextFull = string.Empty;
private ObservableCollection<string> _listItems = new ObservableCollection<string>();
private int _itemCount = 0;
public ViewModel() { }
public string HeaderText
{
get { return _headerText; }
set
{
_headerText = value;
NotifyPropertyChanged("HeaderText");
UpdateHeader();
}
}
public string HeaderTextFull
{
get { return _headerTextFull; }
set
{
_headerTextFull = value;
NotifyPropertyChanged("HeaderTextFull");
}
}
public ObservableCollection<string> ListItems
{
get { return _listItems; }
set
{
_listItems = value;
NotifyPropertyChanged("ListItems");
ItemCount = (_listItems != null ? _listItems.Count : 0);
}
}
public int ItemCount
{
get { return _itemCount; }
set
{
_itemCount = value;
NotifyPropertyChanged("ItemCount");
UpdateHeader();
}
}
private void UpdateHeader()
{
HeaderTextFull = String.Format("{0} ({1})", _headerText, _itemCount);
}
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
The XAML for the Window:
<Window x:Class="SO37192142.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Expander Grid.Row="0" Name="expander1" Header="{Binding Path=HeaderTextFull, FallbackValue='Items'}" IsExpanded="True">
<Grid>
<ListBox Name="listBox1" Width="Auto" Height="Auto" ItemsSource="{Binding Path=ListItems}" />
</Grid>
</Expander>
<Button Grid.Row="1" Content="Add an Item" Click="Button_Click" />
</Grid>
</Window>
The code-behind:
public partial class Window1 : Window
{
ViewModel myModel = new ViewModel();
public Window1()
{
InitializeComponent();
myModel.ListItems.CollectionChanged += new NotifyCollectionChangedEventHandler(ListItems_CollectionChanged);
myModel.HeaderText = "Items";
myModel.ListItems.Add("Item 1");
myModel.ListItems.Add("Item 2");
this.DataContext = myModel;
}
void ListItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
myModel.ItemCount = myModel.ListItems.Count;
}
void Button_Click(object sender, RoutedEventArgs e)
{
myModel.ListItems.Add("Another item");
}
}
When it starts, the Expander header will say "Items (2)". Every time the button is clicked, the header will update to show the new count.
Slight Variation of Above
Here's an example that provides the above example, but also adds a second list to demonstrate a different way. Notice the Expander.Header section.
<Window x:Class="SO37192142.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Expander Grid.Row="0" Grid.Column="0" Name="expander1" Header="{Binding Path=HeaderTextFull, FallbackValue='Items'}" IsExpanded="True">
<Grid>
<ListBox Name="listBox1" Width="Auto" Height="Auto" ItemsSource="{Binding Path=ListItems}" />
</Grid>
</Expander>
<!-- SECOND EXPANDER THAT DOESN'T RELY ON A VIEWMODEL -->
<Expander Grid.Row="0" Grid.Column="1" Name="expander2" IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ElementName=listBox2, Path=Items.Count, UpdateSourceTrigger=PropertyChanged, StringFormat={}Items ({0})}" />
</StackPanel>
</Expander.Header>
<Grid>
<ListBox Name="listBox2" Width="Auto" Height="Auto" ItemsSource="{Binding Path=ListItems}" />
</Grid>
</Expander>
<Button Grid.Row="1" Grid.ColumnSpan="2" Content="Add an Item" Click="Button_Click" />
</Grid>
</Window>
Only Code Behind
If, for some reason, you are just using code-behind, you can do it this way:
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
((INotifyCollectionChanged)listBox1.Items).CollectionChanged += new NotifyCollectionChangedEventHandler(ListBox_CollectionChanged);
}
void ListBox_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
expander1.Header = "Items (" + listBox1.Items.Count + ")";
}
}

Not binding data from one window's Textbox to another window's Textbox

Data Binding from one textbox to another is not happen properly .Here is the below code am using.
EDIT:
Mainwindow xaml:
<Grid>
<TextBox Name="txtBox1" AcceptsReturn="True" Margin="0,0,203,148" VerticalScrollBarVisibility="Visible" LostFocus="txtBox1_LostFocus" TextChanged="txtBox1_TextChanged">
</TextBox>
<Button Content="ButtonToDisplay" Height="46" HorizontalAlignment="Left" Margin="362,71,0,0" Name="button1" VerticalAlignment="Top" Width="98" Click="button1_Click" />
</Grid>
CheckAddressWindow xaml:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="195"/>
<RowDefinition Height="28"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<GroupBox Name="grpFullName" Header="Name Details" BorderBrush="Black" BorderThickness="1" FontWeight="Bold" >
<Grid ShowGridLines="False">
<Grid.RowDefinitions>
<RowDefinition Height="15"/>
<RowDefinition Height="50"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="15"/>
</Grid.RowDefinitions>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.4*"/>
<ColumnDefinition Width="0.7*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Name="lblstreet" Content="Street" VerticalAlignment="Top"></Label>
<TextBox Grid.Column="1" Name="txtStreet" VerticalAlignment="Stretch" Margin="0,0,0,5" TextChanged="txtStreet_TextChanged" Text="{Binding Path=szStreet Mode=OneWay}"></TextBox>
</Grid>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.4*"/>
<ColumnDefinition Width="201"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Name="lblCity" Content="City" VerticalAlignment="Top"></Label>
<TextBox Grid.Column="1" Name="txtCity" VerticalAlignment="Top" Text="{Binding Path=szCityname,Mode=OneWay}"></TextBox>
</Grid>
<Grid Grid.Row="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.4*"/>
<ColumnDefinition Width="0.7*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Name="lblstate" Content="State/Province" VerticalAlignment="Top"></Label>
<TextBox Grid.Column="1" Name="txtState" VerticalAlignment="Top" Text="{Binding Path=szState}"></TextBox>
</Grid>
<Grid Grid.Row="4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.4*"/>
<ColumnDefinition Width="0.7*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Name="lblZip" Content="Zip/PostalCode" VerticalAlignment="Top" Grid.ColumnSpan="2"></Label>
<TextBox Grid.Column="2" Name="txtZip" VerticalAlignment="Top" Text="{Binding Path=iZip}"></TextBox>
</Grid>
<Grid Grid.Row="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.4*"/>
<ColumnDefinition Width="0.7*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Name="lblCountry" Content="Country/Region" VerticalAlignment="Top"></Label>
<ComboBox Grid.Column="1" Name="cbCountry" VerticalAlignment="Top" IsEditable="True" ></ComboBox>
</Grid>
</Grid>
</GroupBox>
<StackPanel Grid.Row="1" Orientation="Horizontal" FlowDirection="LeftToRight">
<CheckBox Name="chkFullAddress" Margin="5,8,5,5" Checked="CheckedEnabled" Unchecked="UncheckedEnabled" IsChecked="true"></CheckBox>
<Label Name="lblFullname" Content="Show this again when name is incomplete or unclear"></Label>
</StackPanel>
<StackPanel Grid.Row="2" Orientation="Horizontal" FlowDirection="RightToLeft">
<Button Name="btnFullnameCancel" Content="Cancel" Margin="10,10,10,10" Width="50" Click="btnCheckAddressCancelClick"></Button>
<Button Name="btnFullnameOk" Content="Ok" Margin="10,10,10,10" Width="50" Click="btnCheckAddressOkClick"></Button>
</StackPanel>
</Grid>
Person.cs code:Edited
public string szStreet
{
get ;
set ;
}
public string szCityname
{
get ;
set ;
}
public string szState { get; set; }
public int iZip { get; set; }
public static bool bCheck { get; set; }
public static bool bCheckFullAddress { get; set; }
Mainwindow LostFocusEvent: Edited
private void txtBox1_LostFocus(object sender, RoutedEventArgs e)
{
if ((!string.IsNullOrEmpty(txtBox1.Text)) && (!string.IsNullOrWhiteSpace(txtBox1.Text)))
{
if (Person.bCheckFullAddress)
{
CheckAddressWindow ca = new CheckAddressWindow(txtBox1);
ca.ShowDialog();
}
}
else
{
CheckAddressWindow ca = new CheckAddressWindow(txtBox1);
ca.chkFullAddress.IsChecked = caObj.chkFullAddress.IsChecked;
ca.txtCity.Text = txtBox1.Text;
ca.ShowDialog();
}
}
ButtonClick event:Edited
private void button1_Click(object sender, RoutedEventArgs e)
{
caObj.chkFullAddress.IsChecked = (Person.bCheckFullAddress == true) ? true : false;
if (!string.IsNullOrEmpty(txtBox1.Text.Trim()))
{
CheckAddressWindow ca = new CheckAddressWindow(txtBox1);
ca.chkFullAddress.IsChecked = caObj.chkFullAddress.IsChecked;
ca.ShowDialog();
}
else
{
CheckAddressWindow ca = new CheckAddressWindow(txtBox1);
ca.chkFullAddress.IsChecked = caObj.chkFullAddress.IsChecked;
ca.ShowDialog();
ca.txtCity.Text = txtBox1.Text;
}
}
CheckAddressWindow.cs:Edited
public partial class CheckAddressWindow : Window
{
public static bool bChecked = true;
Person objPerson = new Person();
bool bCheckAddress = true;
TextBox txt = new TextBox();
public CheckAddressWindow()
{
InitializeComponent();
}
public CheckAddressWindow(TextBox txtName)
{
InitializeComponent();
txt = txtName;
StringCollection objSc = new StringCollection();
int iLinecount = txt.LineCount;
for (int iCount = 0; iCount < iLinecount; iCount++)
{
objSc.Add(txt.GetLineText(iCount));
}
if (objSc.Count.Equals(5))
{
objPerson.szStreet = (objSc[0] + objSc[1]).Trim();
objPerson.szCityname = objSc[2].Trim();
objPerson.szState = objSc[3].Trim();
objPerson.iZip = objSc[4].Trim();
}
if (objSc.Count.Equals(3))
{
objPerson.szStreet = (objSc[0] + objSc[1]).Trim();
string[] arrName = objSc[2].Split(',', ' ');
objPerson.szCityname = arrName[0].Trim();
objPerson.szState = arrName[1].Trim();
objPerson.iZip = arrName[2].Trim();
}
}
private void btnCheckAddressCancelClick(object sender, RoutedEventArgs e)
{
this.Close();
}
private void btnCheckAddressOkClick(object sender, RoutedEventArgs e)
{
if (!string.IsNullOrEmpty(txtCity.Text))
{
//txt.Text = txtStreet.Text + "\n" + txtCity.Text + "\n" + txtState.Text + "\n" + txtZip.Text + "\n" + cbCountry.SelectedValue;
objPerson.szStreet = txtStreet.Text.Trim();
objPerson.szCityname = txtCity.Text.Trim();
objPerson.szState = txtState.Text.Trim();
objPerson.iZip = Convert.ToInt32(txtZip.Text.Trim());
txt.Text = objPerson.szStreet + "\n" +objPerson.szCityname+","+txtState.Text + " " + txtZip.Text;
if (chkFullAddress.IsChecked == true)
{
bCheckAddress = true;
}
else
{
bCheckAddress = false;
}
}
this.Close();
}
private void Window_Loaded_1(object sender, RoutedEventArgs e)
{
cbCountry.Items.Add("India");
cbCountry.Items.Add("US");
cbCountry.SelectedIndex = 0;
}
private void txtStreet_TextChanged(object sender, TextChangedEventArgs e)
{
}
private void CheckedEnabled(object sender, RoutedEventArgs e)
{
chkFullAddress.IsChecked = Person.bCheckFullAddress = true;
}
private void UncheckedEnabled(object sender, RoutedEventArgs e)
{
chkFullAddress.IsChecked = Person.bCheckFullAddress = false;
}
}
}
I am trying to bind data or text entered in mainwindow to checkaddresswindowxaml...as soon as the checkAddresswindow loads it shows all the text feilds are null,if i enter some data in checkaddress feild then click ok button it will show mainwindow.In mainWindow ,when click the button it binding and showing the two text box values.My issue for the first time its binding data to checkAddresswindow.How can i achieve this.am new to this concepts.If i did nay mistakes please rectify me.
Data binding is not happen...where i went wrong and which part of code i need to change to achieve it.
When running your app, do you see any Binding Errors in your debug output window?
I am not seeing where you are setting your DataContext for your CheckAddressWindow. I think you cut off the top of your XAML for that file.
Another problem may be that the "Person" object you are binding to in your CheckAddressWindow is not the same "Person" object being used by the MainWindow.
I would recommend that you have a Model that contains a Person object that both the MainWindow and the CheckAddressWindow bind to. This way, both windows are referring to the same person.
For info and tutorials on MVVM architecture for WPF, see the following link:
MVVM: Tutorial from start to finish?

Focus on a WPF TextBox doesn't work properly with attached properties

In WPF MVVM environment, I'm trying to ensure that focus is given to a TextBox. What happens is that the Cursor appears in the TextBox but is not flashing and the TextBox does not have focus. The code is:
I have a Popup containing this UserControl:
<UserControl x:Class="Rendevous.BusinessModules.AdministrationModule.LogonView"
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="100" d:DesignWidth="300"
xmlns:my="clr-namespace:Csla.Xaml;assembly=Csla.Xaml"
xmlns:ViewModels="clr-namespace:Rendevous.Common.ViewModels;assembly=Common"
Visibility="{Binding Path=IsViewVisible}"
FocusManager.FocusedElement="{Binding Path=passCodeTextBox}"
ViewModels:FocusExtension.IsFocused="{Binding IsPassCodeFocused}">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="Pass Code:"
VerticalAlignment="Center" />
<TextBox Grid.Column="1" Name="passCodeTextBox" Width="100"
VerticalAlignment="Center"
Margin="3"
Text="{Binding Path=PassCode, UpdateSourceTrigger=PropertyChanged}"
ViewModels:FocusExtension.IsFocused="{Binding IsPassCodeFocused}" />
<Button Grid.Column="2" VerticalAlignment="Center" Margin="3" Name="loginButton"
Content="Log In" />
<Button Grid.Column="3"
VerticalAlignment="Center"
Margin="3"
Name="cancelButton"
Content="Cancel" />
</Grid>
(I've removed some Button handling stuff!)
In my ViewModel, I have code like:
public void LogonButtonClicked(object sender, ExecuteEventArgs e)
{
if (securityService.Login(PassCode))
{
eventBroker.Invoke(EventName.CloseLogonView, this);
}
else
{
IsViewVisible = Visibility.Hidden;
msgService.ShowError("Pass Code was not recognised", "Logon Error");
IsViewVisible = Visibility.Visible;
PassCode = "";
IsPassCodeFocused = true;
}
}
I am using an attached property:
public class FocusExtension
{
public static readonly DependencyProperty IsFocusedProperty = DependencyProperty.RegisterAttached("IsFocused", typeof(bool?), typeof(FocusExtension), new FrameworkPropertyMetadata(IsFocusedChanged));
public static bool? GetIsFocused(DependencyObject element)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
return (bool?)element.GetValue(IsFocusedProperty);
}
public static void SetIsFocused(DependencyObject element, bool? value)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
element.SetValue(IsFocusedProperty, value);
}
private static void IsFocusedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement fe = (FrameworkElement)d;
if (e.OldValue == null)
{
fe.GotFocus += FrameworkElement_GotFocus;
fe.LostFocus += FrameworkElement_LostFocus;
}
if ((bool)e.NewValue)
{
fe.Focus();
}
}
private static void FrameworkElement_GotFocus(object sender, RoutedEventArgs e)
{
((FrameworkElement)sender).SetValue(IsFocusedProperty, true);
}
private static void FrameworkElement_LostFocus(object sender, RoutedEventArgs e)
{
((FrameworkElement)sender).SetValue(IsFocusedProperty, false);
}
}
}
What happens is that the cursor appears in the TextBox but is not flashing. The TextBox does not have focus because nothing appears when you type. If you click on it, it works fine.
What have I done wrong?
I couldn't reproduce it using the code you provided, but two things I noticed are:
1) On LogonView, I think your intent was
FocusManager.FocusedElement="{Binding ElementName=passCodeTextBox}"
and not
FocusManager.FocusedElement="{Binding Path=passCodeTextBox}"
2) It looks like IsFocused is applied in multiple places. I'd try setting a breakpoint in IsFocusedChanged() and see which control gets it last.
Between that, and watching FocusManager.FocusedElement ( http://msdn.microsoft.com/en-us/library/system.windows.input.focusmanager.focusedelement.aspx ) and Keyboard.FocusedElement ( http://msdn.microsoft.com/en-us/library/system.windows.input.keyboard.focusedelement ) you should be able to track down where focus is really going.

WPF Drag n drop doesn't fire CommanBinding.CanExecute

Yes, I know it sounds weird, but it doesn't, the question is why, and if there's a work around. It works with everything, even when you hit PrintScreen or Pause keys, CanExecute fires. So after doing a drag drop, in order to make it fire, you have to do "something" else, like a mouse click, focus, hit a key, anything. That'll make the event fire, and allow Execute to happen. Anyway, here's my code, I know it's long, but it'll help you help me.
I found this bug in our large main project, so I simplified it to this little app to isolate the problem.
XAML:
<Window x:Class="DragNDropCommands.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="485" SizeToContent="Width" Loaded="Window_Loaded">
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.New" CanExecute="NewCanExecute" Executed="NewExecuted" />
<CommandBinding Command="ApplicationCommands.Save" CanExecute="SaveCanExecute" Executed="SaveExecuted" />
<CommandBinding Command="ApplicationCommands.Undo" CanExecute="UndoCanExecute" Executed="UndoExecuted" />
<CommandBinding Command="ApplicationCommands.Redo" CanExecute="RedoCanExecute" Executed="RedoExecuted" />
</Window.CommandBindings>
<Grid Margin="8">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Command="ApplicationCommands.New" Grid.Row="0" Grid.Column="0" FontWeight="Bold" Content="New" Width="80" Margin="8"></Button>
<Button Command="ApplicationCommands.Save" Grid.Row="0" Grid.Column="1" FontWeight="Bold" Content="Save" Width="80" Margin="8"></Button>
<Button Command="ApplicationCommands.Undo" Grid.Row="0" Grid.Column="2" FontWeight="Bold" Content="Undo" Width="80" Margin="8"></Button>
<Button Command="ApplicationCommands.Redo" Grid.Row="0" Grid.Column="3" FontWeight="Bold" Content="Redo" Width="80" Margin="8"></Button>
<CheckBox Grid.Row="1" Grid.Column="0" Margin="8" IsChecked="{Binding Path=AllowNew, Mode=TwoWay}">Allow New</CheckBox>
<CheckBox Grid.Row="1" Grid.Column="1" Margin="8" IsChecked="{Binding Path=AllowSave}">Allow Save</CheckBox>
<CheckBox Grid.Row="1" Grid.Column="2" Margin="8" IsChecked="{Binding Path=AllowUndo}">Allow Undo</CheckBox>
<CheckBox Grid.Row="1" Grid.Column="3" Margin="8" IsChecked="{Binding Path=AllowRedo}">Allow Redo</CheckBox>
<Label x:Name="labelDrag" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" BorderBrush="Black" BorderThickness="1" MouseDown="Label_MouseDown"
Background="LightBlue" HorizontalContentAlignment="Center" Margin="8">Drag this label...</Label>
<Label x:Name="labelDropNew" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" BorderBrush="Black" BorderThickness="1" Drop="labelDropNew_Drop"
Background="LightGray" HorizontalContentAlignment="Center" Margin="8" AllowDrop="True">...here to toggle AllowNew</Label>
<Label x:Name="labelDropSave" Grid.Row="3" Grid.Column="2" Grid.ColumnSpan="2" BorderBrush="Black" BorderThickness="1" Drop="labelDropSave_Drop"
Background="LightGray" HorizontalContentAlignment="Center" Margin="8" AllowDrop="True">...here to toggle AllowSave</Label>
<ListBox x:Name="listViewLog" Grid.Row="4" Grid.ColumnSpan="4" Margin="8" Width="500">
</ListBox>
<Button Grid.Row="5" Grid.Column="1" Grid.ColumnSpan="2" Margin="8" Click="Button_Click">Clear list</Button>
</Grid>
</Window>
C#:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace DragNDropCommands
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
private CommandControl commandControl = new CommandControl();
private int canExecuteCount = 1;
public Window1()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = commandControl;
}
private void NewCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (this.commandControl == null || listViewLog == null)
return;
e.CanExecute = this.commandControl.AllowNew;
listViewLog.Items.Add
(
String.Format
(
"{0} - NewCanExecute: {1} - commandControl.AllowNew: {2}",
canExecuteCount++, e.CanExecute, commandControl.AllowNew
)
);
}
private void NewExecuted(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("New executed");
}
private void SaveCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (this.commandControl == null || listViewLog == null)
return;
e.CanExecute = this.commandControl.AllowSave;
listViewLog.Items.Add
(
String.Format
(
"{0} - SaveCanExecute: {1} - commandControl.AllowSave: {2}",
canExecuteCount++, e.CanExecute, commandControl.AllowSave
)
);
}
private void SaveExecuted(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Save executed");
}
private void UndoCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (this.commandControl == null || listViewLog == null)
return;
e.CanExecute = this.commandControl.AllowUndo;
listViewLog.Items.Add
(
String.Format
(
"{0} - UndoCanExecute: {1} - commandControl.AllowUndo: {2}",
canExecuteCount++, e.CanExecute, commandControl.AllowUndo
)
);
}
private void UndoExecuted(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Undo executed");
}
private void RedoCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (this.commandControl == null || listViewLog == null)
return;
e.CanExecute = this.commandControl.AllowRedo;
listViewLog.Items.Add
(
String.Format
(
"{0} - RedoCanExecute: {1} - commandControl.AllowRedo: {2}",
canExecuteCount++, e.CanExecute, commandControl.AllowRedo
)
);
}
private void RedoExecuted(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Redo executed");
}
private void Button_Click(object sender, RoutedEventArgs e)
{
listViewLog.Items.Clear();
}
private void Label_MouseDown(object sender, MouseButtonEventArgs e)
{
Label label = (Label)sender;
if(e.LeftButton == MouseButtonState.Pressed)
DragDrop.DoDragDrop(label, label, DragDropEffects.Move);
}
private void labelDropNew_Drop(object sender, DragEventArgs e)
{
this.commandControl.AllowNew = !this.commandControl.AllowNew;
}
private void labelDropSave_Drop(object sender, DragEventArgs e)
{
this.commandControl.AllowSave = !this.commandControl.AllowSave;
}
}
public class CommandControl : DependencyObject
{
public bool AllowNew
{
get { return (bool)GetValue(AllowNewProperty); }
set { SetValue(AllowNewProperty, value); }
}
// Using a DependencyProperty as the backing store for AllowNew. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AllowNewProperty =
DependencyProperty.Register("AllowNew", typeof(bool), typeof(CommandControl), new UIPropertyMetadata(false));
public bool AllowSave
{
get { return (bool)GetValue(AllowSaveProperty); }
set { SetValue(AllowSaveProperty, value); }
}
// Using a DependencyProperty as the backing store for AllowSave. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AllowSaveProperty =
DependencyProperty.Register("AllowSave", typeof(bool), typeof(CommandControl), new UIPropertyMetadata(false));
public bool AllowUndo
{
get { return (bool)GetValue(AllowUndoProperty); }
set { SetValue(AllowUndoProperty, value); }
}
// Using a DependencyProperty as the backing store for AllowUndo. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AllowUndoProperty =
DependencyProperty.Register("AllowUndo", typeof(bool), typeof(CommandControl), new UIPropertyMetadata(false));
public bool AllowRedo
{
get { return (bool)GetValue(AllowRedoProperty); }
set { SetValue(AllowRedoProperty, value); }
}
// Using a DependencyProperty as the backing store for AllowRedo. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AllowRedoProperty =
DependencyProperty.Register("AllowRedo", typeof(bool), typeof(CommandControl), new UIPropertyMetadata(false));
}
}
You should be able to just copy paste and do a few name changes (files, namespaces) to get it running. I'd really love your help since this has been driving me nuts, and now that I finally discover the reason for the bug, I don't know what to do about it.
Any suggestion is really apreciatted.
Thanks in advance.
Just a quick suggestion:
You could use CommandManager.InvalidateRequerySuggested() in the drag and drop event handler to force the reexecution of CanExecute(). (Link)

Resources