简体   繁体   English

在WPF中更改Textblock背景,颜色更改后会自行重置

[英]Changing Textblock background in WPF resetting itself after color change

I have a textblock in a WPF usercontrol defined as: 我在WPF用户控件中有一个文本块,定义为:

<TextBlock Grid.Column="0"
           Text="{Binding RecognitionResults}"
           Background="{Binding ResultBackground}" />

The UserControl in which the TextBlock is displayed is being presented as a String from another UserControl as: 显示TextBlockUserControl从另一个UserControlString形式呈现为:

<ItemsControl ItemsSource="{Binding Strings}" >
      <ItemsControl.ItemContainerStyle>
           <Style>
                <Setter Property="Control.Margin"
                        Value="{Binding Margin}"/>
           </Style>
      </ItemsControl.ItemContainerStyle>
 </ItemsControl>  

Essentially, the ItemsControl is presenting a list of "Strings", each string itself being represented by its own UserControl . 本质上, ItemsControl呈现了一个“字符串”列表,每个字符串本身由其自己的UserControl表示。

Now, when I Tap on the display of the TextBlock , the gesture performs this action to change the background color from yellow to green in the ViewModel: 现在,当我点击TextBlock的显示时,手势将执行以下操作以在ViewModel中将背景颜色从黄色更改为绿色:

public void Refill()
{
    ResultBackground = Brushes.Green;
}

The ResultBackground color is defined in the ViewModel as: ResultBackground颜色在ViewModel中定义为:

 private SolidColorBrush resultbackground =
     (SolidColorBrush)new BrushConverter().ConvertFromString("#FFEFF100");

 public SolidColorBrush ResultBackground
 {
      get
      {
           Console.WriteLine("Now getting resultbackground of "
               + resultbackground);
           return resultbackground;
      }
      set
      {
          if (resultbackground != value)
          {
              resultbackground = value;
              OnPropertyChanged("ResultBackground");
          }
      }
 }

So, when I physically tap on the TextBlock , the gesture will successfully turn it from yellow to green. 因此,当我实际点击TextBlock ,该手势将成功将其从黄色变为绿色。 So far so good. 到现在为止还挺好。

However, when I execute the Refill() method from a command (ie, a menu command), the TextBlock first turns the green (like it should) but then redisplays as the initial yellow. 但是,当我从命令(即菜单命令)执行Refill()方法时, TextBlock首先变成绿色(应有的样子),然后重新显示为初始黄色。 Watching the output from the Console.WriteLine above confirms that the get is first called to turn the box green from Refill() , but then (there is no stack trace), the get is called again (without the set being called) that retrieves yellow! 观察上面的Console.WriteLine的输出,确认首先调用get来使Refill()的框变为绿色,但是随后(没有堆栈跟踪),再次调用get(不调用该集)以检索黄色!

I am at a complete loss as to why this is happening or what to do to fix it. 我完全不知道为什么会发生这种情况或如何解决它。 The only places in code where ResultBackground is even referenced is in the above code. 在代码中ResultBackground甚至引用ResultBackground地方就是上述代码。

Any help in getting this to work would be most appreciated. 非常感谢您对此工作的任何帮助。

Edit: I don't know if it is relevant or not, but the command that executes refill() is being executed as an Action from the menu as: 编辑:我不知道它是否相关,但是执行refill()的命令正在从菜单中作为Action执行,如下所示:

 <UserControl x:Class="Nova5.UI.Views.Ink.InkView"
        ............................

<UserControl.Resources>
    <Style x:Key="MenuItemStyle" TargetType="{x:Type MenuItem}">
         <Setter Property="Command" Value="{Binding OnSelected}" />
    </Style>
</UserControl.Resources>


<Grid>
    <Grid.Resources>
        <HierarchicalDataTemplate DataType="{x:Type m:MyMenuItem}" ItemsSource="{Binding Path=SubItems}">
            <ContentPresenter
                Content="{Binding Path=DisplayText}"
                RecognizesAccessKey="True" />
        </HierarchicalDataTemplate>
    </Grid.Resources>

    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="25" />
    </Grid.RowDefinitions>

    <Menu Grid.Row="3" Height="28" >
        <MenuItem Header="Options" ItemsSource="{Binding OptionSubItems}" DisplayMemberPath="{Binding DisplayText}" >
            <MenuItem.ItemContainerStyle>
                <Style>
                    <Setter Property="MenuItem.Command"  Value="{Binding OnSelected}"/>
                </Style>
            </MenuItem.ItemContainerStyle>
        </MenuItem>
    </Menu>

</Grid>

Where OptionSubItems is built in the viewmodel constructor as: 其中,在视图模型构造函数中将OptionSubItems构建为:

  OptionSubItems = new ObservableCollection<MyMenuItem>();

and MyMenuItem is: MyMenuItem是:

   public class MyMenuItem : MenuItemBase
{
    private Action Command;

    public MyMenuItem(String DisplayText, Action command)
    {
        this.DisplayText = DisplayText;

        this.Command = command;
    }
    public override void OnItemSelected()
    {
        this.Command();
    }
}

The ViewModel constructor dynamically builds the command list as: ViewModel构造函数动态生成命令列表,如下所示:

    OptionSubItems.Add(new MyMenuItem("Refill", delegate()
        {
            CurrentViewModelDetails.ExecuteMenuCommand("Refill");
        }));

and ExecuteMenuCommand does: ExecuteMenuCommand可以:

     if (commandname == "RefillAllCurrentPrescriptions")
        {

            for (int k = 0; k < Strings.Count; k++)
            {
                Strings[k].refill();
            }
        }

Hope this helps. 希望这可以帮助。 (I wondering if the problem is in the above xaml with two bindings to the OnSelected from different styles?) (我想知道问题是否出在上面的xaml中,并且具有从不同样式到OnSelected的两个绑定吗?)

OK, at risk of total embarrassment, here is the original code that was causing the blinking problem: 好吧,冒着完全尴尬的风险,这是引起闪烁问题的原始代码:

 OptionSubItems.Add(new MyMenuItem("Refill all current prescriptions", delegate()
        {
            CurrentViewModelDetails.ExecuteMenuCommand("RefillAllCurrentPrescriptions");
             CurrentViewModelDetails.RefreshDisplay(RxViews.PrescriptionList);
            DialogTitle = "Current Prescriptions";
        }));

The RefreshDisplay() method was rebuilding the display from the database and totally dropping the effects of the refill() --which explains why breakpoints placed on the get{} did not show any stack trace. RefreshDisplay()方法从数据库中重建显示,完全丢弃的影响refill()可呈现解释了为什么放置在断点get{}没有显示任何堆栈跟踪。 The get{} were being called by the XAML when the new objects were created; 创建新对象时,XAML会调用get{} there was no set{} involved. 没有涉及set{} So the above code actually works fine (after I removed the offending line to be more concise for SO). 因此,上面的代码实际上运行良好(在我删除了有问题的行以使SO更简洁之后)。

To give credit where credit is due, it was Rachel's suggestion that led to restudying the delegates, but thanks to all for the help. 为了在应有的信誉下给予荣誉,是瑞秋的建议导致对代表们进行重新研究,但感谢所有人的帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM