Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF基于属性将文本添加到TextBlock_C#_Wpf_Textblock - Fatal编程技术网

C# WPF基于属性将文本添加到TextBlock

C# WPF基于属性将文本添加到TextBlock,c#,wpf,textblock,C#,Wpf,Textblock,我有一个列表视图,其中有一列显示两个字母的状态通知。 基于布尔属性(HasWorkState)的值,我想在HasWorkState=false时在状态缩写周围添加括号 例如: HasWorkState=truedisplayOH HasWorkState=false显示(哦) 州缩写显示在GridViewColumn中: <!-- Work State --> <GridViewColumn Width="{Binding ActualWidth,

我有一个
列表视图
,其中有一列显示两个字母的状态通知。 基于布尔属性(
HasWorkState
)的值,我想在
HasWorkState=false
时在状态缩写周围添加括号

例如:

  • HasWorkState=true
    display
    OH
  • HasWorkState=false
    显示
    (哦)
州缩写显示在
GridViewColumn
中:

<!-- Work State -->
<GridViewColumn Width="{Binding ActualWidth, 
                          RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}, 
                          Converter={StaticResource MathConverter}, ConverterParameter=(x/10)*0.5}">
    <GridViewColumn.Header>
        <GridViewColumnHeader Content=" State"
                              HorizontalContentAlignment="Left" />
    </GridViewColumn.Header>
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding WorkState}"
                       Style="{StaticResource StateStyle}" />
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

我知道当
HasWorkState=false
时显示
工具提示时,此样式的应用是正确的。我只需要知道如何添加括号。我目前为
文本设置的
值设置器不起作用。

最好的方法是将该属性添加到视图模型中。在视图模型中类似于以下内容:

internal class StateStyleViewModel : INotifyPropertyChanged
{
    private bool hasWorkState;
    private string workState;
    public event PropertyChangedEventHandler PropertyChanged;

    private string WorkState
    {
        get { return workState; }
        set
        {
            if (value == workState) return;
            workState = value;
            OnPropertyChanged();
            //Notify that the value of the dependent property has changed.
            OnPropertyChanged(nameof(DisplayWorkState));
        }
    }

    public bool HasWorkState
    {
        get { return hasWorkState; }
        set
        {
            if (value == hasWorkState) return;
            hasWorkState = value;
            OnPropertyChanged();
            //Notify that the value of the dependent property has changed.
            OnPropertyChanged(nameof(DisplayWorkState));
        }
    }

    /// <summary>
    /// Property for binding
    /// </summary>
    public string DisplayWorkState => HasWorkState ? WorkState : $"({WorkState})";

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
内部类StateStyleViewModel:INotifyPropertyChanged
{
私人布尔州;
私有字符串工作状态;
公共事件属性更改事件处理程序属性更改;
私有字符串工作状态
{
获取{返回工作状态;}
设置
{
如果(值==工作状态)返回;
工作状态=值;
OnPropertyChanged();
//通知从属属性的值已更改。
OnPropertyChanged(名称(显示工作状态));
}
}
公共布尔州
{
获取{return hasWorkState;}
设置
{
if(value==hasWorkState)返回;
hasWorkState=值;
OnPropertyChanged();
//通知从属属性的值已更改。
OnPropertyChanged(名称(显示工作状态));
}
}
/// 
///用于绑定的属性
/// 
公共字符串DisplayWorkState=>HasWorkState?WorkState:$“({WorkState})”;
[NotifyPropertyChangedInvocator]
受保护的虚拟void OnPropertyChanged([CallerMemberName]字符串propertyName=null)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
}

然后只需绑定到DisplayWorkState而不是WorkState,最好的方法是将该属性添加到视图模型中。在视图模型中类似于以下内容:

internal class StateStyleViewModel : INotifyPropertyChanged
{
    private bool hasWorkState;
    private string workState;
    public event PropertyChangedEventHandler PropertyChanged;

    private string WorkState
    {
        get { return workState; }
        set
        {
            if (value == workState) return;
            workState = value;
            OnPropertyChanged();
            //Notify that the value of the dependent property has changed.
            OnPropertyChanged(nameof(DisplayWorkState));
        }
    }

    public bool HasWorkState
    {
        get { return hasWorkState; }
        set
        {
            if (value == hasWorkState) return;
            hasWorkState = value;
            OnPropertyChanged();
            //Notify that the value of the dependent property has changed.
            OnPropertyChanged(nameof(DisplayWorkState));
        }
    }

    /// <summary>
    /// Property for binding
    /// </summary>
    public string DisplayWorkState => HasWorkState ? WorkState : $"({WorkState})";

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
内部类StateStyleViewModel:INotifyPropertyChanged
{
私人布尔州;
私有字符串工作状态;
公共事件属性更改事件处理程序属性更改;
私有字符串工作状态
{
获取{返回工作状态;}
设置
{
如果(值==工作状态)返回;
工作状态=值;
OnPropertyChanged();
//通知从属属性的值已更改。
OnPropertyChanged(名称(显示工作状态));
}
}
公共布尔州
{
获取{return hasWorkState;}
设置
{
if(value==hasWorkState)返回;
hasWorkState=值;
OnPropertyChanged();
//通知从属属性的值已更改。
OnPropertyChanged(名称(显示工作状态));
}
}
/// 
///用于绑定的属性
/// 
公共字符串DisplayWorkState=>HasWorkState?WorkState:$“({WorkState})”;
[NotifyPropertyChangedInvocator]
受保护的虚拟void OnPropertyChanged([CallerMemberName]字符串propertyName=null)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
}

然后,您只需绑定到DisplayWorkState而不是WorkState,您已经找到了一个解决方案,但值得了解出现问题的原因:因为您正在使用TextBlock元素上的属性设置
Text
,因此样式无法覆盖该属性。如果使用样式设置器应用默认的
{Binding WorkState}
,则样式将能够覆盖它

我更喜欢这样的观点,所以我的方法是:

<ContentControl Content="{Binding WorkState}" Style="{StaticResource StateStyle}" />

国家风格:

<Style x:Key="StateStyle" TargetType="ContentControl">
    <Style.Triggers>
        <DataTrigger Binding="{Binding HasWorkState}" Value="False">
            <!-- Leave the content alone and just change the format string -->
            <Setter Property="ContentStringFormat" Value="({0})" />

            <Setter 
                Property="ToolTip" 
                Value="Work location unspecified. Using residence state." 
                />
        </DataTrigger>
    </Style.Triggers>
</Style>

您已经找到了一个解决方案,但值得了解问题的原因:因为您正在使用TextBlock元素上的属性设置
Text
,因此样式无法覆盖该属性。如果使用样式设置器应用默认的
{Binding WorkState}
,则样式将能够覆盖它

我更喜欢这样的观点,所以我的方法是:

<ContentControl Content="{Binding WorkState}" Style="{StaticResource StateStyle}" />

国家风格:

<Style x:Key="StateStyle" TargetType="ContentControl">
    <Style.Triggers>
        <DataTrigger Binding="{Binding HasWorkState}" Value="False">
            <!-- Leave the content alone and just change the format string -->
            <Setter Property="ContentStringFormat" Value="({0})" />

            <Setter 
                Property="ToolTip" 
                Value="Work location unspecified. Using residence state." 
                />
        </DataTrigger>
    </Style.Triggers>
</Style>


聪明的解决方案!从未想过以这种方式应用lambda运算符。聪明的解决方案!从未想过以这种方式应用lambda运算符。谢谢,实际上我更喜欢这种方法,因为它可以在XAML中保留所有与显示相关的更改。@BrianKE,你使用它了吗?我刚刚设置了一个测试项目。我做了,风格上有一个错误导致了这个问题。很抱歉浪费你的时间。@BrianKE一点也不。我没有测试过它,这总是有风险的。谢谢你,实际上我更喜欢这种方法,因为它可以在XAML中保留所有与显示相关的更改。@BrianKE你让它工作了吗?我刚刚设置了一个测试项目。我做了,风格上有一个错误导致了这个问题。很抱歉浪费你的时间。@BrianKE一点也不。我没有测试过,这总是有风险的。