【发布时间】:2017-03-09 23:16:16
【问题描述】:
我的项目中有两个窗口(MainWindow 和一个用于 MainWindow 控件的某些属性的小窗口)。在主窗口的一个选项卡中,有一个分为十列的网格。在每一列中都有一些控件。下面是我的项目的示例代码。
如果我检查周期(属性窗口中的复选框)标签(主窗口)为“周期”,并且当我检查频率(属性窗口中的复选框)标签(主窗口)为“频率”时,我想要。
我希望,当我选中 PropertiesWindow(周期或频率)中的一个复选框时,MainWindow 上的标签(lb_freq1)根据选中的 CheckBox 的内容更改其内容。 (此外,在time_div1(Label)处显示的所选单位)。
第一个解决方案:
XAML 主窗口:
<Window x:Class="wpf1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-wpf1"
mc:Ignorable="d"
Title="wpf1" Height="720" Width="1280" WindowStartupLocation="CenterScreen" Icon="kkk.bmp" Background="#FFE0E0E0" Foreground="#FF49A81D" BorderBrush="#FFB93838" >
<Grid>
<TabControl x:Name="tabControl">
<TabItem Header="Tab1">
<Grid>
<StackPanel>
<Label x:Name="lb_freq1" Content="Period" HorizontalAlignment="Center" Margin="0,10,0,0" />
<StackPanel Orientation="Horizontal" Margin="0" HorizontalAlignment="Center">
<TextBox x:Name="txt_freq1" Width="50" Height="20" HorizontalContentAlignment="Right" BorderThickness="1,1,0,1" HorizontalAlignment="Left" VerticalContentAlignment="Center"/>
<Label x:Name="time_div1" Content="us" Width="20" BorderThickness="0,1,1,1" Margin="0" HorizontalAlignment="Right" Height="20" Padding="0" BorderBrush="#FFABADB3" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" />
</StackPanel>
<Label x:Name="lb_width1" Content="Pulse Width" HorizontalAlignment="Center" Margin="0,10,0,0" />
<StackPanel Orientation="Horizontal" Margin="0" HorizontalAlignment="Center">
<TextBox x:Name="txt_width1" Width="50" Height="20" HorizontalContentAlignment="Right" BorderThickness="1,1,0,1" HorizontalAlignment="Left"/>
<Label x:Name="pv_div1" Content="us" Width="20" BorderThickness="0,1,1,1" Margin="0" HorizontalAlignment="Right" Height="20" Padding="0" BorderBrush="#FFABADB3" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" />
</StackPanel>
<Button x:Name="Properties1" Content="Properties" Margin="10,30,10,10" HorizontalAlignment="Center" BorderBrush="Blue" Click="Properties1_Click" />
</StackPanel>
</Grid>
</TabItem>
</TabControl>
</Grid>
</Window>
已编辑 主窗口背后的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Globalization;
using System.ComponentModel;
namespace wpf1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
ViewModel viewModel = new ViewModel();
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
}
private void Properties1_Click(object sender, RoutedEventArgs e)
{
string res1 = lb_freq1.Content.ToString();
string res3 = time_div1.Content.ToString();
var newWindow = new PWMProperties();
newWindow.Owner = this;
newWindow.ShowDialog();
string result1 = newWindow.Value1;
if (result1 == null)
{
lb_freq1.Content = res1;
}
else
{
lb_freq1.Content = result1;
}
string result3 = newWindow.Unit1;
if (result3 == null)
{
time_div1.Content = res3;
}
else
{
time_div1.Content = result3;
}
}
}
}
XAML 属性窗口:
<Window x:Class="wpf1.PWMProperties"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:wpf1"
mc:Ignorable="d"
Title="Properties" Height="335" Width="285" ResizeMode="NoResize" BorderThickness="0" WindowStartupLocation="CenterOwner">
<Window.Resources>
<local:BoolConverter2 x:Key="Converter"></local:BoolConverter2>
<local:BoolConverter x:Key="Reverse"></local:BoolConverter>
</Window.Resources>
<Grid>
<StackPanel VerticalAlignment="Top" Margin="0,10,0,0" HorizontalAlignment="Center">
<StackPanel Orientation="Horizontal" Margin="0,0,0,20">
<StackPanel Margin="0,0,49,0">
<RadioButton x:Name="SelectPeriod" Content="Period" Margin="0,0,0,0" Click="SelectPeriod_Click" />
<ComboBox x:Name="PeriodUnits" Padding="3,2,2,2" IsReadOnly="True" IsEditable="True" Text="us" IsEnabled="{Binding ElementName=SelectPeriod, Path=IsChecked}" SelectionChanged="PeriodUnits_SelectionChanged"
ItemsSource="{Binding PeriodComboBoxItems}">
</ComboBox>
</StackPanel>
<StackPanel Margin="20,0,0,0">
<RadioButton x:Name="SelectFrequency" Content="Frequency" Click="SelectFrequency_Click" />
<ComboBox x:Name="FrequencyUnits" Padding="3,2,2,2" IsReadOnly="True" IsEditable="True" Text="Hz" IsEnabled="{Binding ElementName=SelectFrequency, Path=IsChecked}" SelectionChanged="FrequencyUnits_SelectionChanged"
ItemsSource="{Binding FrequencyComboBoxItems}">
</ComboBox>
</StackPanel>
</StackPanel>
</StackPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" Margin="0">
<Button x:Name="OkButton" Content="OK" Margin="135,5,10,5" Click="OkButton_Click" Width="60" />
<Button x:Name="CancelButton" Content="Cancel" Click="CancelButton_Click" Width="60" Margin="0,5,10,5" />
</StackPanel>
</Grid>
</Window>
已编辑 属性窗口背后的代码:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.ComponentModel;
using System.IO;
using System.Xml;
using System.Windows.Markup;
namespace wpf1
{
/// <summary>
/// Interaction logic for Analog.xaml
/// </summary>
public partial class PWMProperties : Window
{
public ObservableCollection<string> PeriodComboBoxItems { get; set; }
public ObservableCollection<string> FrequencyComboBoxItems { get; set; }
public ObservableCollection<string> PulseWidthComboBoxItems { get; set;}
public PWMProperties()
{
InitializeComponent();
this.DataContext = this;
this.PeriodComboBoxItems = new ObservableCollection<string>() { "us", "ms", "s" };
this.FrequencyComboBoxItems = new ObservableCollection<string>() { "Hz", "kHz", "MHz" };
this.PulseWidthComboBoxItems = new ObservableCollection<string>() { "us", "ms", "s" };
}
string val1, val2, unit1, unit2;
private void OkButton_Click(object sender, RoutedEventArgs e)
{
if (SelectPeriod.IsChecked == true)
{
val1 = "Period";
if (unit1 == null || unit1!="ms") unit1 = "us";
}
if (SelectFrequency.IsChecked == true)
{
val1 = "Frequency";
if (unit1 == null || unit1!="kHz") unit1 = "Hz";
}
DialogResult = true;
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
DialogResult = false;
}
public string Value1 { get { return val1; } }
public string Value2 { get { return val2; } }
public string Unit1 { get { return unit1; } }
public string Unit2 { get { return unit2; } }
private void PeriodUnits_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
unit1 = PeriodUnits.SelectedItem.ToString();
}
private void FrequencyUnits_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
unit1 = FrequencyUnits.SelectedItem.ToString();
}
}
public class BoolConverter2 : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
bool v = (bool)value;
return v;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new System.NotSupportedException();
}
}
}
第二种可能的解决方案:
然后,我在我的 MainWindow 代码中添加了一个 ViewModel:
public class ViewModel : INotifyPropertyChanged
{
private string _value1 = "Period";
public event PropertyChangedEventHandler PropertyChanged;
public string Value1
{
get { return _value1; }
set
{
_value1 = value;
OnPropertyChanged("Value1");
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
所以,PropertiesWindow 后面的大部分代码都被删除了,我使用 Binding 来更改 MainWindow 的 lb_freq1(Label)。
<Label x:Name="lb_freq1" Content="{Binding Value1, Mode=TwoWay}" HorizontalAlignment="Center" Margin="0,10,0,0" />
我不知道如何从那个状态继续。我是 WPF 和 C# 的新手,如果有人能以任何方式帮助我,我将不胜感激。
主要问题
我已经编辑了我的第一个解决方案,所以如果有人可以看一下。我现在设法做的几乎就是我想要的。但有个问题。我希望,当我单击 OK.Button 时,我在 Properties.Window 所做的“设置”应该更改 MainWindow 的标签。虽然,当我单击右上角的 Cancel.Button 或 Close.Button 时,在 Properties.Window 上所做的任何更改都不应该更改 MainWindow 上的标签。
此外,当我关闭 Properties.Window,然后再次打开它时,CheckBoxes 和 ComboBox.SelectedItems 需要具有与 Properties.Window 关闭时相同的状态。但这不会发生。
【问题讨论】:
-
您希望属性窗口与主窗口同时打开和编辑吗?例如,您是否希望同时访问和编辑两个窗口?我的意思是,“属性”窗口可以是一个对话框吗?
-
@GingerNinja - 我编辑了我的代码并使我的问题更加具体。也许,现在,你可以给我一些建议。提前致谢。
-
@Chrislo,这仍然没有真正回答我的问题。我更关心功能。因为如果您可以在属性窗口打开时无法访问主窗口,则可以使用 ShowDialog。然后要获取数据的更新,您可以使用 DialogResult 和视图模型。我通常为“编辑”对话框窗口执行此操作。但如果你想使用
Show()而不是ShowDialog(),它就不会那么顺利
标签: c# wpf data-binding