c# - WPF - 基于 listviewitem 选择的更改控件。控件不更新

标签 c# wpf mvvm controltemplates

我正在尝试根据用户选择的 listviewitem 更新主窗口上的控件,但是当 listviewitem 选择发生更改时,控件不会更新。

我用这篇文章作为引用 How to dynamically change a WPF control's template using a checkbox?

编辑:我最初使用 ContentTemplate 但根据建议将其更改为 DataTemplate ,但它仍然没有更新

我的主窗口的 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;
    }
}

使用 MainWindowProperties 类
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;
        }

这将使用“费用储备自动化”或“财务关闭状态”更新我的 ViewModel 中的 SelectedProcess

我知道我的 ViewModel 的 DataContext 设置正确(但可能不是 ContentControl),因为我能够使用新消息更新 lbxProgress 并使用应用程序 RunTime 更新 txtRunTime

但是,当我更改 lvProcessSelection 上的选择时,什么也没有发生; ERAFileSelect 的默认控件仍然存在。

有人能指出我如何解决这个问题的正确方向吗?

最佳答案

Could anybody point me in the right direction on how to solve this?



您的 MainWindowProperties 类应实现 INotifyPropertyChanged 接口(interface),并在 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));
    }
}

有关此通用接口(interface)的详细信息,请参阅 MSDN:https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx

您绑定(bind)到的每个 View 模型/模型都必须实现此接口(interface)并针对要更新的 View 中的任何目标值发出更改通知。

关于c# - WPF - 基于 listviewitem 选择的更改控件。控件不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41166845/

相关文章:

c# - Log4net 记录到 Oracle 在记录到数字字段时抛出错误?

c# - 进行拆分并将结果转换为整数的最佳方法

c# - 从任务工厂调度的线程更新 WPF 中的 UI 的正确方法是什么?

javascript - ko.subscribe 子模型属性

c# - Autofac Resolve<IEnumerable<T>>() 返回空列表

c# - 退出按钮以关闭 C# 中的 Windows 窗体窗体

wpf - AvalonDock 现在失去了 Alt Key 装饰

wpf - 使用 MVVM 和 WPF 登录 - 登录对象必须在其他窗口中使用。 (全局化)

c# - WPF MVVM 组合框 SelectionChanged/SelectedItem

ios - RxSwift 的结构 View 模型