WPF - 基于 listviewitem 选择的更改控件。控件不更新
WPF - Change Controls based on listviewitem selection. Controls not updating
我正在尝试根据用户选择的 listviewitem 更新我的 Main Window 上的控件,但是当 listviewitem 选择更改时,控件不会更新。
我用这个post作为参考How to dynamically change a WPF control's template using a checkbox?
编辑:我最初使用 ContentTemplate,但根据建议将其更改为 DataTemplate,但它仍然没有更新
我的 Main Window 的 XMAL 是
<Window.Resources>
<DataTemplate x:Key="Default">
<Grid Margin="20,280,0,0" />
</DataTemplate>
<DataTemplate x:Key="ERAFileSelect">
<Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="218" Margin="20,280,0,0" VerticalAlignment="Top" Width="257" CornerRadius="15">
<Grid Name="grdFileSelect">
<Label x:Name="lblProcessContent" Content="Drag File or Manually Select File" HorizontalAlignment="Center" VerticalAlignment="Top" Width="257" HorizontalContentAlignment="Center"/>
<TextBox x:Name="txtEraFileName" HorizontalAlignment="Left" Height="23" Margin="10,80,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="235"/>
<Button x:Name="btnSelectFiles" Content="Manually Select File(s)" HorizontalAlignment="Left" Margin="10,161,0,0" VerticalAlignment="Top" Width="235" Height="45"/>
</Grid>
</Border>
</DataTemplate>
<DataTemplate x:Key="FCSFileSelect">
<Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="218" Margin="20,280,0,0" VerticalAlignment="Top" Width="257" CornerRadius="15">
<Grid Name="grdFileSelect">
<Label x:Name="lblProcessContent" Content="Drag File or Manually Select Files" HorizontalAlignment="Center" VerticalAlignment="Top" Width="257" HorizontalContentAlignment="Center"/>
<TextBox x:Name="txtFCSFileName_TQ02" HorizontalAlignment="Left" Height="23" Margin="10,40,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="174"/>
<Button x:Name="btnSelectFiles_TQ02" Content="Select" HorizontalAlignment="Left" Margin="189,37,0,0" VerticalAlignment="Top" Width="56" Height="28"/>
<TextBox x:Name="txtFCSFileName_TQ11" HorizontalAlignment="Left" Height="23" Margin="10,105,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="174"/>
<Button x:Name="btnSelectFiles_TQ11" Content="Selec" HorizontalAlignment="Left" Margin="189,100,0,0" VerticalAlignment="Top" Width="56" Height="28"/>
<TextBox x:Name="txtFCSFileName_TQ16" HorizontalAlignment="Left" Height="23" Margin="10,170,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="174"/>
<Button x:Name="btnSelectFiles_TQ16" Content="Select" HorizontalAlignment="Left" Margin="189,165,0,0" VerticalAlignment="Top" Width="56" Height="28"/>
</Grid>
</Border>
</DataTemplate>
</Window.Resources>
<Grid Margin="0,0,2,0">
<GroupBox x:Name="gbxProgress" Header="Progress" HorizontalAlignment="Left" Margin="298,105,0,0" VerticalAlignment="Top" Height="445" Width="462" Foreground="Black">
<ListBox x:Name="lbxProgress" HorizontalAlignment="Left" Height="408" Margin="10,10,0,0" VerticalAlignment="Top" Width="431" Foreground="Black" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Progress.Message}" />
</GroupBox>
<Button x:Name="btnStart" Content="Start" HorizontalAlignment="Left" Margin="20,513,0,0" VerticalAlignment="Top" Width="100" Height="37" IsEnabled="{Binding Properties.StartButtonEnabled}" Click="btnStart_Click"/>
<Button x:Name="btnCancel" Content="Cancel" HorizontalAlignment="Left" Margin="177,513,0,0" VerticalAlignment="Top" Width="100" Height="37"/>
<Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="70" Margin="20,21,0,0" VerticalAlignment="Top" Width="740" CornerRadius="15">
<Grid>
<Image HorizontalAlignment ="Left" Margin="10" Height="50" Width="50" VerticalAlignment="Center" Source="/Lib/Icons/User.png" />
<TextBlock Name="txtUser" FontSize="20" Height="30" Width="200" Foreground="Red" HorizontalAlignment="Left" Margin="78,19,0,19"/>
<Image HorizontalAlignment ="Left" Margin="443,8,0,10" Height="50" Width="50" VerticalAlignment="Center" Source="Lib/Icons/Watch.png" />
<TextBlock x:Name="txtRunTime" FontSize="20" Height="30" Width="200" Foreground="Red" HorizontalAlignment="Left" Margin="519,19,0,19" Text="{Binding AppRunTime.TimeElapsed}" />
</Grid>
</Border>
<Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="144" Margin="20,119,0,0" VerticalAlignment="Top" Width="257" CornerRadius="15">
<Grid>
<Label x:Name="lblProcessSelection" Content="Process Selection" HorizontalAlignment="Center" VerticalAlignment="Top" Width="257" HorizontalContentAlignment="Center"/>
<ListView x:Name="lvProcessSelection" HorizontalAlignment="Left" Height="93" Margin="10,30,0,0" VerticalAlignment="Top" Width="235" BorderThickness="0" SelectionChanged="lvProcessSelection_SelectionChanged">
<ListViewItem Name="itmERA" Content="Expense Reserve Automation"/>
<ListViewItem Name="itmFCS" Content="Financial Close Status"/>
<ListViewItem Name="itmPEL" Content="Peel"/>
</ListView>
</Grid>
</Border>
<ContentControl DataContext="{Binding Properties}" Content="{Binding}">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="ContentTemplate" Value="{StaticResource ERAFileSelect}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedProcess}" Value="Expense Reserve Automation">
<Setter Property="ContentTemplate" Value="{StaticResource ERAFileSelect}" />
</DataTrigger>
<DataTrigger Binding="{Binding SelectedProcess}" Value="Financial Close Status">
<Setter Property="ContentTemplate" Value="{StaticResource FCSFileSelect}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</Grid>
ViewModel 代码为
public class MainWindowModel
{
public ApplicationRunTime AppRunTime { get; set; }
public LogMessage Progress { get; set; }
public MainWindowProperties Properties { get; set; }
public MainWindowModel()
{
AppRunTime = new ApplicationRunTime();
Progress = new LogMessage();
Properties = new MainWindowProperties();
Properties.StartButtonEnabled = false;
}
}
具有主要Window属性class
public class MainWindowProperties
{
public bool StartButtonEnabled { get; set; }
public string SelectedProcess { get; set; }
}
在我的 MainWindow 构造函数中,我设置了 DataContext
mainWindowModel = new MainWindowModel();
this.DataContext = mainWindowModel;
当 lvProcessSelection 中的选择发生变化时,将执行以下代码
if (lvProcessSelection.SelectedItems.Count > 0)
{
mainWindowModel.Properties.SelectedProcess = ((ListViewItem)lvProcessSelection.SelectedItem).Content.ToString();
}
else
{
mainWindowModel.Properties.SelectedProcess = string.Empty;
}
这将使用 "Expense Reserve Automation" 或 "Financial Close Status"
更新我的 ViewModel 中的 SelectedProcess
我知道我的 ViewModel 的 DataContext 设置正确(但可能不适用于 ContentControl),因为我能够使用新消息更新 lbxProgress 并使用应用程序 RunTime 更新 txtRunTime
然而,当我更改 lvProcessSelection 上的选择时,没有任何反应; ERAFileSelect 的默认控件保留。
任何人都可以指出正确的方向来解决这个问题吗?
为什么不使用数据模板?数据模板将在这种情况下工作。
Could anybody point me in the right direction on how to solve this?
您的 MainWindowProperties class 应该实现 INotifyPropertyChanged 接口并在 SelectedProcess 属性 设置为新值时发出更改通知:
public class MainWindowProperties : INotifyPropertyChanged
{
public bool StartButtonEnabled { get; set; }
private string _selectedProcess;
public string SelectedProcess
{
get { return _selectedProcess; }
set { _selectedProcess = value; NotifyPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
请参阅 MSDN 以获取有关此公共接口的更多信息:https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx
您绑定到的每个视图 model/model 都必须实现此接口并为要更新的视图中的任何目标值发出更改通知。
我正在尝试根据用户选择的 listviewitem 更新我的 Main Window 上的控件,但是当 listviewitem 选择更改时,控件不会更新。
我用这个post作为参考How to dynamically change a WPF control's template using a checkbox?
编辑:我最初使用 ContentTemplate,但根据建议将其更改为 DataTemplate,但它仍然没有更新
我的 Main Window 的 XMAL 是
<Window.Resources>
<DataTemplate x:Key="Default">
<Grid Margin="20,280,0,0" />
</DataTemplate>
<DataTemplate x:Key="ERAFileSelect">
<Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="218" Margin="20,280,0,0" VerticalAlignment="Top" Width="257" CornerRadius="15">
<Grid Name="grdFileSelect">
<Label x:Name="lblProcessContent" Content="Drag File or Manually Select File" HorizontalAlignment="Center" VerticalAlignment="Top" Width="257" HorizontalContentAlignment="Center"/>
<TextBox x:Name="txtEraFileName" HorizontalAlignment="Left" Height="23" Margin="10,80,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="235"/>
<Button x:Name="btnSelectFiles" Content="Manually Select File(s)" HorizontalAlignment="Left" Margin="10,161,0,0" VerticalAlignment="Top" Width="235" Height="45"/>
</Grid>
</Border>
</DataTemplate>
<DataTemplate x:Key="FCSFileSelect">
<Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="218" Margin="20,280,0,0" VerticalAlignment="Top" Width="257" CornerRadius="15">
<Grid Name="grdFileSelect">
<Label x:Name="lblProcessContent" Content="Drag File or Manually Select Files" HorizontalAlignment="Center" VerticalAlignment="Top" Width="257" HorizontalContentAlignment="Center"/>
<TextBox x:Name="txtFCSFileName_TQ02" HorizontalAlignment="Left" Height="23" Margin="10,40,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="174"/>
<Button x:Name="btnSelectFiles_TQ02" Content="Select" HorizontalAlignment="Left" Margin="189,37,0,0" VerticalAlignment="Top" Width="56" Height="28"/>
<TextBox x:Name="txtFCSFileName_TQ11" HorizontalAlignment="Left" Height="23" Margin="10,105,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="174"/>
<Button x:Name="btnSelectFiles_TQ11" Content="Selec" HorizontalAlignment="Left" Margin="189,100,0,0" VerticalAlignment="Top" Width="56" Height="28"/>
<TextBox x:Name="txtFCSFileName_TQ16" HorizontalAlignment="Left" Height="23" Margin="10,170,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="174"/>
<Button x:Name="btnSelectFiles_TQ16" Content="Select" HorizontalAlignment="Left" Margin="189,165,0,0" VerticalAlignment="Top" Width="56" Height="28"/>
</Grid>
</Border>
</DataTemplate>
</Window.Resources>
<Grid Margin="0,0,2,0">
<GroupBox x:Name="gbxProgress" Header="Progress" HorizontalAlignment="Left" Margin="298,105,0,0" VerticalAlignment="Top" Height="445" Width="462" Foreground="Black">
<ListBox x:Name="lbxProgress" HorizontalAlignment="Left" Height="408" Margin="10,10,0,0" VerticalAlignment="Top" Width="431" Foreground="Black" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Progress.Message}" />
</GroupBox>
<Button x:Name="btnStart" Content="Start" HorizontalAlignment="Left" Margin="20,513,0,0" VerticalAlignment="Top" Width="100" Height="37" IsEnabled="{Binding Properties.StartButtonEnabled}" Click="btnStart_Click"/>
<Button x:Name="btnCancel" Content="Cancel" HorizontalAlignment="Left" Margin="177,513,0,0" VerticalAlignment="Top" Width="100" Height="37"/>
<Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="70" Margin="20,21,0,0" VerticalAlignment="Top" Width="740" CornerRadius="15">
<Grid>
<Image HorizontalAlignment ="Left" Margin="10" Height="50" Width="50" VerticalAlignment="Center" Source="/Lib/Icons/User.png" />
<TextBlock Name="txtUser" FontSize="20" Height="30" Width="200" Foreground="Red" HorizontalAlignment="Left" Margin="78,19,0,19"/>
<Image HorizontalAlignment ="Left" Margin="443,8,0,10" Height="50" Width="50" VerticalAlignment="Center" Source="Lib/Icons/Watch.png" />
<TextBlock x:Name="txtRunTime" FontSize="20" Height="30" Width="200" Foreground="Red" HorizontalAlignment="Left" Margin="519,19,0,19" Text="{Binding AppRunTime.TimeElapsed}" />
</Grid>
</Border>
<Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="144" Margin="20,119,0,0" VerticalAlignment="Top" Width="257" CornerRadius="15">
<Grid>
<Label x:Name="lblProcessSelection" Content="Process Selection" HorizontalAlignment="Center" VerticalAlignment="Top" Width="257" HorizontalContentAlignment="Center"/>
<ListView x:Name="lvProcessSelection" HorizontalAlignment="Left" Height="93" Margin="10,30,0,0" VerticalAlignment="Top" Width="235" BorderThickness="0" SelectionChanged="lvProcessSelection_SelectionChanged">
<ListViewItem Name="itmERA" Content="Expense Reserve Automation"/>
<ListViewItem Name="itmFCS" Content="Financial Close Status"/>
<ListViewItem Name="itmPEL" Content="Peel"/>
</ListView>
</Grid>
</Border>
<ContentControl DataContext="{Binding Properties}" Content="{Binding}">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="ContentTemplate" Value="{StaticResource ERAFileSelect}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedProcess}" Value="Expense Reserve Automation">
<Setter Property="ContentTemplate" Value="{StaticResource ERAFileSelect}" />
</DataTrigger>
<DataTrigger Binding="{Binding SelectedProcess}" Value="Financial Close Status">
<Setter Property="ContentTemplate" Value="{StaticResource FCSFileSelect}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</Grid>
ViewModel 代码为
public class MainWindowModel
{
public ApplicationRunTime AppRunTime { get; set; }
public LogMessage Progress { get; set; }
public MainWindowProperties Properties { get; set; }
public MainWindowModel()
{
AppRunTime = new ApplicationRunTime();
Progress = new LogMessage();
Properties = new MainWindowProperties();
Properties.StartButtonEnabled = false;
}
}
具有主要Window属性class
public class MainWindowProperties
{
public bool StartButtonEnabled { get; set; }
public string SelectedProcess { get; set; }
}
在我的 MainWindow 构造函数中,我设置了 DataContext
mainWindowModel = new MainWindowModel();
this.DataContext = mainWindowModel;
当 lvProcessSelection 中的选择发生变化时,将执行以下代码
if (lvProcessSelection.SelectedItems.Count > 0)
{
mainWindowModel.Properties.SelectedProcess = ((ListViewItem)lvProcessSelection.SelectedItem).Content.ToString();
}
else
{
mainWindowModel.Properties.SelectedProcess = string.Empty;
}
这将使用 "Expense Reserve Automation" 或 "Financial Close Status"
更新我的 ViewModel 中的 SelectedProcess我知道我的 ViewModel 的 DataContext 设置正确(但可能不适用于 ContentControl),因为我能够使用新消息更新 lbxProgress 并使用应用程序 RunTime 更新 txtRunTime
然而,当我更改 lvProcessSelection 上的选择时,没有任何反应; ERAFileSelect 的默认控件保留。
任何人都可以指出正确的方向来解决这个问题吗?
为什么不使用数据模板?数据模板将在这种情况下工作。
Could anybody point me in the right direction on how to solve this?
您的 MainWindowProperties class 应该实现 INotifyPropertyChanged 接口并在 SelectedProcess 属性 设置为新值时发出更改通知:
public class MainWindowProperties : INotifyPropertyChanged
{
public bool StartButtonEnabled { get; set; }
private string _selectedProcess;
public string SelectedProcess
{
get { return _selectedProcess; }
set { _selectedProcess = value; NotifyPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
请参阅 MSDN 以获取有关此公共接口的更多信息:https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx
您绑定到的每个视图 model/model 都必须实现此接口并为要更新的视图中的任何目标值发出更改通知。